summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/editing/finder
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-16 09:59:13 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-20 10:28:53 +0000
commit6c11fb357ec39bf087b8b632e2b1e375aef1b38b (patch)
treec8315530db18a8ee566521c39ab8a6af4f72bc03 /chromium/third_party/blink/renderer/core/editing/finder
parent3ffaed019d0772e59d6cdb2d0d32fe4834c31f72 (diff)
downloadqtwebengine-chromium-6c11fb357ec39bf087b8b632e2b1e375aef1b38b.tar.gz
BASELINE: Update Chromium to 74.0.3729.159
Change-Id: I8d2497da544c275415aedd94dd25328d555de811 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/editing/finder')
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc223
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h67
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc582
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc34
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h2
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/editing/finder/text_finder.h10
8 files changed, 765 insertions, 187 deletions
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index b3c08463402..a4f828bbf6c 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h"
#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_select_element.h"
#include "third_party/blink/renderer/core/invisible_dom/invisible_dom.h"
#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
@@ -23,9 +24,9 @@
namespace blink {
-FindBuffer::FindBuffer(const PositionInFlatTree& start_position) {
- DCHECK(start_position.ComputeContainerNode());
- CollectTextUntilBlockBoundary(*start_position.ComputeContainerNode());
+FindBuffer::FindBuffer(const EphemeralRangeInFlatTree& range) {
+ DCHECK(range.IsNotNull() && !range.IsCollapsed()) << range;
+ CollectTextUntilBlockBoundary(range);
}
FindBuffer::Results::Results() {
@@ -34,16 +35,17 @@ FindBuffer::Results::Results() {
FindBuffer::Results::Results(const Vector<UChar>& buffer,
String search_text,
- const mojom::blink::FindOptions& options) {
+ const blink::FindOptions options) {
// We need to own the |search_text| because |text_searcher_| only has a
// StringView (doesn't own the search text).
search_text_ = search_text;
- text_searcher_.SetPattern(search_text_, options.match_case);
+ text_searcher_.SetPattern(search_text_, options);
text_searcher_.SetText(buffer.data(), buffer.size());
text_searcher_.SetOffset(0);
}
-FindBuffer::Results::Iterator::Iterator(TextSearcherICU* text_searcher)
+FindBuffer::Results::Iterator::Iterator(TextSearcherICU* text_searcher,
+ String search_text)
: text_searcher_(text_searcher), has_match_(true) {
operator++();
}
@@ -63,13 +65,29 @@ FindBuffer::Results::Iterator FindBuffer::Results::begin() {
if (empty_result_)
return end();
text_searcher_.SetOffset(0);
- return Iterator(&text_searcher_);
+ return Iterator(&text_searcher_, search_text_);
}
FindBuffer::Results::Iterator FindBuffer::Results::end() const {
return Iterator();
}
+bool FindBuffer::Results::IsEmpty() {
+ return begin() == end();
+}
+
+FindBuffer::BufferMatchResult FindBuffer::Results::front() {
+ return *begin();
+}
+
+FindBuffer::BufferMatchResult FindBuffer::Results::back() {
+ Iterator last_result;
+ for (Iterator it = begin(); it != end(); ++it) {
+ last_result = it;
+ }
+ return *last_result;
+}
+
unsigned FindBuffer::Results::CountForTesting() {
unsigned result = 0;
for (Iterator it = begin(); it != end(); ++it) {
@@ -79,15 +97,23 @@ unsigned FindBuffer::Results::CountForTesting() {
}
void FindBuffer::InvisibleLayoutScope::EnsureRecalc(Node& block_root) {
+ if (!RuntimeEnabledFeatures::InvisibleDOMEnabled())
+ return;
if (did_recalc_)
return;
did_recalc_ = true;
DCHECK(block_root.GetDocument().Lifecycle().GetState() >=
DocumentLifecycle::kStyleClean);
+ // If we're in an invisible subtree, we should recalc style from the invisible
+ // root/the highest ancestor of |block_root| with the invisible attribute,
+ // otherwise we should recalc from |block_root|.
+ // InvisibleRoot is always non-null when IsInsideInvisibleSubtree is true.
if (InvisibleDOM::IsInsideInvisibleSubtree(block_root))
invisible_root_ = InvisibleDOM::InvisibleRoot(block_root);
else
invisible_root_ = &ToElement(block_root);
+
+ DCHECK(invisible_root_);
invisible_root_->GetDocument().SetFindInPageRoot(invisible_root_);
invisible_root_->SetNeedsStyleRecalc(
kSubtreeStyleChange,
@@ -100,6 +126,8 @@ void FindBuffer::InvisibleLayoutScope::EnsureRecalc(Node& block_root) {
}
FindBuffer::InvisibleLayoutScope::~InvisibleLayoutScope() {
+ if (!RuntimeEnabledFeatures::InvisibleDOMEnabled())
+ return;
if (!did_recalc_)
return;
invisible_root_->GetDocument().SetFindInPageRoot(nullptr);
@@ -117,17 +145,19 @@ bool ShouldIgnoreContents(const Node& node) {
IsHTMLIFrameElement(element) || IsHTMLImageElement(element) ||
IsHTMLLegendElement(element) || IsHTMLMeterElement(element) ||
IsHTMLObjectElement(element) || IsHTMLProgressElement(element) ||
- IsHTMLSelectElement(element) || IsHTMLStyleElement(element) ||
- IsHTMLScriptElement(element) || IsHTMLVideoElement(element) ||
- IsHTMLAudioElement(element) ||
+ (IsHTMLSelectElement(element) &&
+ ToHTMLSelectElement(element).UsesMenuList()) ||
+ IsHTMLStyleElement(element) || IsHTMLScriptElement(element) ||
+ IsHTMLVideoElement(element) || IsHTMLAudioElement(element) ||
(element.GetDisplayLockContext() &&
- !element.GetDisplayLockContext()->IsSearchable());
+ !element.GetDisplayLockContext()->IsActivatable());
}
-Node* GetDisplayNoneAncestor(const Node& node) {
+Node* GetNonSearchableAncestor(const Node& node) {
for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(node)) {
const ComputedStyle* style = ancestor.EnsureComputedStyle();
- if (style && style->Display() == EDisplay::kNone)
+ if ((style && style->Display() == EDisplay::kNone) ||
+ ShouldIgnoreContents(ancestor))
return &ancestor;
if (ancestor.IsDocumentNode())
return nullptr;
@@ -144,7 +174,7 @@ bool IsBlock(EDisplay display) {
Node* GetVisibleTextNode(Node& start_node) {
Node* node = &start_node;
// Move to outside display none subtree if we're inside one.
- while (Node* ancestor = GetDisplayNoneAncestor(*node)) {
+ while (Node* ancestor = GetNonSearchableAncestor(*node)) {
if (ancestor->IsDocumentNode())
return nullptr;
node = FlatTreeTraversal::NextSkippingChildren(*ancestor);
@@ -184,9 +214,56 @@ Node& GetLowestDisplayBlockInclusiveAncestor(const Node& start_node) {
return *start_node.GetDocument().documentElement();
}
+EphemeralRangeInFlatTree FindBuffer::FindMatchInRange(
+ const EphemeralRangeInFlatTree& range,
+ String search_text,
+ FindOptions options) {
+ if (!range.StartPosition().IsConnected())
+ return EphemeralRangeInFlatTree();
+
+ EphemeralRangeInFlatTree last_match_range;
+ Node* first_node = range.StartPosition().NodeAsRangeFirstNode();
+ Node* past_last_node = range.EndPosition().NodeAsRangePastLastNode();
+ Node* node = first_node;
+ while (node && node != past_last_node) {
+ if (GetNonSearchableAncestor(*node)) {
+ node = FlatTreeTraversal::NextSkippingChildren(*node);
+ continue;
+ }
+ if (!node->IsTextNode()) {
+ node = FlatTreeTraversal::Next(*node);
+ continue;
+ }
+ // If we're in the same node as the start position, start from the start
+ // position instead of the start of this node.
+ PositionInFlatTree start_position =
+ node == first_node ? range.StartPosition()
+ : PositionInFlatTree::FirstPositionInNode(*node);
+ if (start_position >= range.EndPosition())
+ break;
+
+ FindBuffer buffer(
+ EphemeralRangeInFlatTree(start_position, range.EndPosition()));
+ std::unique_ptr<Results> match_results =
+ buffer.FindMatches(search_text, options);
+ if (!match_results->IsEmpty()) {
+ if (!(options & kBackwards)) {
+ BufferMatchResult match = match_results->front();
+ return buffer.RangeFromBufferIndex(match.start,
+ match.start + match.length);
+ }
+ BufferMatchResult match = match_results->back();
+ last_match_range =
+ buffer.RangeFromBufferIndex(match.start, match.start + match.length);
+ }
+ node = buffer.PositionAfterBlock().ComputeContainerNode();
+ }
+ return last_match_range;
+}
+
std::unique_ptr<FindBuffer::Results> FindBuffer::FindMatches(
const WebString& search_text,
- const mojom::blink::FindOptions& options) const {
+ const blink::FindOptions options) const {
if (buffer_.IsEmpty() || search_text.length() > buffer_.size())
return std::make_unique<Results>();
String search_text_16_bit = search_text;
@@ -195,12 +272,54 @@ std::unique_ptr<FindBuffer::Results> FindBuffer::FindMatches(
return std::make_unique<Results>(buffer_, search_text_16_bit, options);
}
+bool FindBuffer::PushScopedForcedUpdateIfNeeded(const Element& element) {
+ if (auto* context = element.GetDisplayLockContext()) {
+ DCHECK(context->IsActivatable());
+ scoped_forced_update_list_.push_back(context->GetScopedForcedUpdate());
+ return true;
+ }
+ return false;
+}
+
+void FindBuffer::CollectScopedForcedUpdates(Node& start_node,
+ const Node* search_range_end_node,
+ const Node* node_after_block) {
+ if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+ return;
+ if (start_node.GetDocument().LockedDisplayLockCount() ==
+ start_node.GetDocument().ActivationBlockingDisplayLockCount())
+ return;
+
+ Node* node = &start_node;
+ // We assume |start_node| is always visible/activatable if locked, so we don't
+ // need to check activatability of ancestors here.
+ for (Node& ancestor : FlatTreeTraversal::InclusiveAncestorsOf(*node)) {
+ if (!ancestor.IsElementNode())
+ continue;
+ PushScopedForcedUpdateIfNeeded(ToElement(ancestor));
+ }
+
+ while (node && node != node_after_block && node != search_range_end_node) {
+ if (ShouldIgnoreContents(*node)) {
+ // Will skip display:none/non-activatable locked subtrees/etc.
+ node = FlatTreeTraversal::NextSkippingChildren(*node);
+ continue;
+ }
+ if (node->IsElementNode())
+ PushScopedForcedUpdateIfNeeded(ToElement(*node));
+ node = FlatTreeTraversal::Next(*node);
+ }
+}
+
// Collects text until block boundary located at or after |start_node|
// to |buffer_|. Saves the next starting node after the block to
// |node_after_block_|.
-void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
- // Get first visible text node from |start_node|.
- Node* node = GetVisibleTextNode(start_node);
+void FindBuffer::CollectTextUntilBlockBoundary(
+ const EphemeralRangeInFlatTree& range) {
+ DCHECK(range.IsNotNull() && !range.IsCollapsed()) << range;
+ // Get first visible text node from |start_position|.
+ Node* node =
+ GetVisibleTextNode(*range.StartPosition().NodeAsRangeFirstNode());
if (!node || !node->isConnected()) {
node_after_block_ = nullptr;
return;
@@ -212,7 +331,8 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
// Calculate layout tree and style for invisible nodes inside the whole
// subtree of |block_ancestor|.
- if (node && InvisibleDOM::IsInsideInvisibleSubtree(*node))
+ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() && node &&
+ InvisibleDOM::IsInsideInvisibleSubtree(*node))
invisible_layout_scope_.EnsureRecalc(block_ancestor);
// Collect all text under |block_ancestor| to |buffer_|,
@@ -221,8 +341,23 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
// Will try to collect all text in outer div but will actually
// stop when it encounters the inner div. So buffer will be "abc".
Node* const first_traversed_node = node;
+ // We will also stop if we encountered/passed |end_node|.
+ Node* end_node = range.EndPosition().NodeAsRangeLastNode();
+
+ if (node) {
+ CollectScopedForcedUpdates(*node, end_node, just_after_block);
+ if (!scoped_forced_update_list_.IsEmpty())
+ node->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+ }
+
while (node && node != just_after_block) {
if (ShouldIgnoreContents(*node)) {
+ if (end_node && (end_node == node ||
+ FlatTreeTraversal::IsDescendantOf(*end_node, *node))) {
+ // For setting |node_after_block| later.
+ node = FlatTreeTraversal::NextSkippingChildren(*node);
+ break;
+ }
// Move the node so we wouldn't encounter this node or its descendants
// later.
if (!IsHTMLWBRElement(ToHTMLElement(*node)))
@@ -230,7 +365,8 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
node = FlatTreeTraversal::NextSkippingChildren(*node);
continue;
}
- if (node->IsElementNode() && ToElement(node)->HasInvisibleAttribute() &&
+ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() &&
+ node->IsElementNode() && ToElement(node)->HasInvisibleAttribute() &&
!invisible_layout_scope_.DidRecalc()) {
// We found and invisible node. Calculate the layout & style for the whole
// block at once, and we need to recalculate the NGOffsetMapping and start
@@ -238,7 +374,6 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
mapping_needs_recalc_ = true;
node = first_traversed_node;
last_block_flow = nullptr;
- offset_mapping_storage_ = nullptr;
buffer_.clear();
invisible_layout_scope_.EnsureRecalc(block_ancestor);
continue;
@@ -248,6 +383,12 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
// This element and its descendants are not visible, skip it.
// We can safely just check the computed style of this node since
// we guarantee |block_ancestor| is visible.
+ if (end_node && (end_node == node ||
+ FlatTreeTraversal::IsDescendantOf(*end_node, *node))) {
+ // For setting |node_after_block| later.
+ node = FlatTreeTraversal::NextSkippingChildren(*node);
+ break;
+ }
node = FlatTreeTraversal::NextSkippingChildren(*node);
if (node && !FlatTreeTraversal::IsDescendantOf(*node, block_ancestor))
break;
@@ -270,10 +411,13 @@ void FindBuffer::CollectTextUntilBlockBoundary(Node& start_node) {
break;
}
if (!last_block_flow) {
- DCHECK(!offset_mapping_storage_);
last_block_flow = &block_flow;
}
- AddTextToBuffer(text_node, block_flow);
+ AddTextToBuffer(text_node, block_flow, range);
+ }
+ if (node == end_node) {
+ node = FlatTreeTraversal::Next(*node);
+ break;
}
node = FlatTreeTraversal::Next(*node);
}
@@ -323,23 +467,27 @@ PositionInFlatTree FindBuffer::PositionAtEndOfCharacterAtIndex(
}
void FindBuffer::AddTextToBuffer(const Text& text_node,
- LayoutBlockFlow& block_flow) {
+ LayoutBlockFlow& block_flow,
+ const EphemeralRangeInFlatTree& range) {
if (!offset_mapping_ || mapping_needs_recalc_) {
- offset_mapping_ =
- NGInlineNode::GetOffsetMapping(&block_flow, &offset_mapping_storage_);
+ offset_mapping_ = NGInlineNode::GetOffsetMapping(&block_flow);
mapping_needs_recalc_ = false;
}
- const String mapped_text = offset_mapping_->GetText();
- const NGMappingUnitRange range =
- offset_mapping_->GetMappingUnitsForNode(text_node);
+
+ Position node_start =
+ (&text_node == range.StartPosition().ComputeContainerNode())
+ ? ToPositionInDOMTree(range.StartPosition().ToOffsetInAnchor())
+ : Position::FirstPositionInNode(text_node);
+ Position node_end =
+ (&text_node == range.EndPosition().ComputeContainerNode())
+ ? ToPositionInDOMTree(range.EndPosition().ToOffsetInAnchor())
+ : Position::LastPositionInNode(text_node);
unsigned last_unit_end = 0;
bool first_unit = true;
- for (const NGOffsetMappingUnit& unit : range) {
- String text_for_unit =
- mapped_text.Substring(unit.TextContentStart(),
- unit.TextContentEnd() - unit.TextContentStart());
- text_for_unit.Ensure16Bit();
- text_for_unit.Replace('\n', kObjectReplacementCharacter);
+ const String mapped_text = offset_mapping_->GetText();
+ for (const NGOffsetMappingUnit& unit :
+ offset_mapping_->GetMappingUnitsForDOMRange(
+ EphemeralRange(node_start, node_end))) {
if (first_unit || last_unit_end != unit.TextContentStart()) {
// This is the first unit, or the units are not consecutive, so we need to
// insert a new BufferNodeMapping.
@@ -347,6 +495,11 @@ void FindBuffer::AddTextToBuffer(const Text& text_node,
BufferNodeMapping({buffer_.size(), unit.TextContentStart()}));
first_unit = false;
}
+ String text_for_unit =
+ mapped_text.Substring(unit.TextContentStart(),
+ unit.TextContentEnd() - unit.TextContentStart());
+ text_for_unit.Ensure16Bit();
+ text_for_unit.Replace('\n', kObjectReplacementCharacter);
buffer_.Append(text_for_unit.Characters16(), text_for_unit.length());
last_unit_end = unit.TextContentEnd();
}
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
index 80ea303f223..be236144f80 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer.h
@@ -5,8 +5,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_FINDER_FIND_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_FINDER_FIND_BUFFER_H_
-#include "third_party/blink/public/mojom/frame/find_in_page.mojom-blink.h"
-#include "third_party/blink/renderer/core/editing/finder/find_buffer.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
+#include "third_party/blink/renderer/core/editing/finder/find_options.h"
#include "third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
@@ -23,13 +23,26 @@ class CORE_EXPORT FindBuffer {
STACK_ALLOCATED();
public:
- FindBuffer(const PositionInFlatTree& start_position);
+ explicit FindBuffer(const EphemeralRangeInFlatTree& range);
+
+ static EphemeralRangeInFlatTree FindMatchInRange(
+ const EphemeralRangeInFlatTree& range,
+ String search_text,
+ const FindOptions);
// A match result, containing the starting position of the match and
// the length of the match.
struct BufferMatchResult {
const unsigned start;
const unsigned length;
+
+ bool operator==(const BufferMatchResult& other) const {
+ return start == other.start && length == other.length;
+ }
+
+ bool operator!=(const BufferMatchResult& other) const {
+ return !operator==(other);
+ }
};
// All match results for this buffer. We can iterate through the
@@ -40,13 +53,13 @@ class CORE_EXPORT FindBuffer {
Results(const Vector<UChar>& buffer,
String search_text,
- const mojom::blink::FindOptions& options);
+ const blink::FindOptions options);
class CORE_EXPORT Iterator
: public std::iterator<std::forward_iterator_tag, BufferMatchResult> {
public:
Iterator() = default;
- Iterator(TextSearcherICU* text_searcher);
+ Iterator(TextSearcherICU* text_searcher, String search_text_);
bool operator==(const Iterator& other) {
return has_match_ == other.has_match_;
@@ -70,18 +83,23 @@ class CORE_EXPORT FindBuffer {
Iterator end() const;
+ bool IsEmpty();
+
+ BufferMatchResult front();
+
+ BufferMatchResult back();
+
unsigned CountForTesting();
private:
- bool empty_result_ = false;
String search_text_;
TextSearcherICU text_searcher_;
+ bool empty_result_ = false;
};
// Finds all the match for |search_text| in |buffer_|.
- std::unique_ptr<Results> FindMatches(
- const WebString& search_text,
- const mojom::blink::FindOptions& options) const;
+ std::unique_ptr<Results> FindMatches(const WebString& search_text,
+ const blink::FindOptions options) const;
// Gets a flat tree range corresponding to text in the [start_index,
// end_index) of |buffer|.
@@ -95,12 +113,25 @@ class CORE_EXPORT FindBuffer {
}
private:
- // Collects text for one LayoutBlockFlow located at or after |start_node|
- // to |buffer_|, might be stopped without finishing one full LayoutBlockFlow
- // if we encountered another LayoutBLockFlow. Saves the next starting node
- // after the block (first node in another LayoutBlockFlow) to
- // |node_after_block_|.
- void CollectTextUntilBlockBoundary(Node& start_node);
+ // Collects text for one LayoutBlockFlow located within |range| to |buffer_|,
+ // might be stopped without finishing one full LayoutBlockFlow if we
+ // encountered another LayoutBLockFlow, or if the end of |range| is
+ // surpassed. Saves the next starting node after the block (first node in
+ // another LayoutBlockFlow or after |end_position|) to |node_after_block_|.
+ void CollectTextUntilBlockBoundary(const EphemeralRangeInFlatTree& range);
+
+ // Adds the ScopedForcedUpdate of |element|'s DisplayLockContext (if it's
+ // there) to |scoped_forced_update_list_|. Returns true if we added a
+ // ScopedForceUpdate.
+ bool PushScopedForcedUpdateIfNeeded(const Element& element);
+
+ // Collects all ScopedForceUpdates of any activatable-locked element
+ // within the range of [start_node, search_range_end_node] or
+ // [start_node, node_after_block) whichever is smaller, to
+ // |scoped_forced_update_list_|.
+ void CollectScopedForcedUpdates(Node& start_node,
+ const Node* search_range_end_node,
+ const Node* node_after_block);
class CORE_EXPORT InvisibleLayoutScope {
STACK_ALLOCATED();
@@ -153,12 +184,16 @@ class CORE_EXPORT FindBuffer {
PositionInFlatTree PositionAtEndOfCharacterAtIndex(unsigned index) const;
- void AddTextToBuffer(const Text& text_node, LayoutBlockFlow& block_flow);
+ // Adds text in |text_node| that are located within |range| to |buffer_|.
+ void AddTextToBuffer(const Text& text_node,
+ LayoutBlockFlow& block_flow,
+ const EphemeralRangeInFlatTree& range);
InvisibleLayoutScope invisible_layout_scope_;
Member<Node> node_after_block_;
Vector<UChar> buffer_;
Vector<BufferNodeMapping> buffer_node_mappings_;
+ Vector<DisplayLockContext::ScopedForcedUpdate> scoped_forced_update_list_;
// For legacy layout, we need to save a unique_ptr of the NGOffsetMapping
// because nobody owns it. In LayoutNG, the NGOffsetMapping is owned by
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc
index 71cb1338c28..88638e533e5 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_buffer_test.cc
@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/editing/finder/find_buffer.h"
+#include "build/build_config.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
@@ -12,9 +13,18 @@ namespace blink {
class FindBufferTest : public EditingTestBase {
protected:
- PositionInFlatTree FirstPosition() {
- return PositionInFlatTree::FirstPositionInNode(
- *GetDocument().documentElement());
+ PositionInFlatTree LastPositionInDocument() {
+ return GetDocument().documentElement()->lastChild()
+ ? PositionInFlatTree::AfterNode(
+ *GetDocument().documentElement()->lastChild())
+ : PositionInFlatTree::LastPositionInNode(
+ *GetDocument().documentElement());
+ }
+
+ EphemeralRangeInFlatTree WholeDocumentRange() {
+ return EphemeralRangeInFlatTree(PositionInFlatTree::FirstPositionInNode(
+ *GetDocument().documentElement()),
+ LastPositionInDocument());
}
PositionInFlatTree PositionFromParentId(const char* id, unsigned offset) {
@@ -32,10 +42,10 @@ TEST_F(FindBufferTest, FindInline) {
"<div id='container'>a<span id='span'>b</span><b id='b'>c</b><div "
"id='none' style='display:none'>d</div><div id='inline-div' "
"style='display: inline;'>e</div></div>");
- FindBuffer buffer(FirstPosition());
+ FindBuffer buffer(WholeDocumentRange());
EXPECT_TRUE(buffer.PositionAfterBlock().IsNull());
std::unique_ptr<FindBuffer::Results> results =
- buffer.FindMatches("abce", *mojom::blink::FindOptions::New());
+ buffer.FindMatches("abce", kCaseInsensitive);
EXPECT_EQ(1u, results->CountForTesting());
FindBuffer::BufferMatchResult match = *results->begin();
EXPECT_EQ(0u, match.start);
@@ -51,7 +61,7 @@ TEST_F(FindBufferTest, RangeFromBufferIndex) {
"<div id='container'>a <span id='span'> b</span><b id='b'>cc</b><div "
"id='none' style='display:none'>d</div><div id='inline-div' "
"style='display: inline;'>e</div></div>");
- FindBuffer buffer(FirstPosition());
+ FindBuffer buffer(WholeDocumentRange());
// Range for "a"
EXPECT_EQ(EphemeralRangeInFlatTree(PositionFromParentId("container", 0),
PositionFromParentId("container", 1)),
@@ -126,155 +136,513 @@ TEST_F(FindBufferTest, RangeFromBufferIndex) {
SerializeRange(buffer.RangeFromBufferIndex(1, 4)));
}
+TEST_F(FindBufferTest, FindBetweenPositionsSameNode) {
+ PositionInFlatTree start_position =
+ ToPositionInFlatTree(SetCaretTextToBody("f|oofoo"));
+ Node* node = start_position.ComputeContainerNode();
+ // |end_position| = foofoo| (end of text).
+ PositionInFlatTree end_position =
+ PositionInFlatTree::LastPositionInNode(*node);
+ FindBuffer buffer(EphemeralRangeInFlatTree(start_position, end_position));
+ EXPECT_EQ(1u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(4u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // |start_position| = fo|ofoo
+ // |end_position| = foof|oo
+ start_position = PositionInFlatTree(*node, 2u);
+ end_position = PositionInFlatTree(*node, 4u);
+ buffer = FindBuffer(EphemeralRangeInFlatTree(start_position, end_position));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, FindBetweenPositionsDifferentNodes) {
+ SetBodyContent(
+ "<div id='div'>foo<span id='span'>foof<b id='b'>oo</b></span></div>");
+ Element* div = GetElementById("div");
+ Element* span = GetElementById("span");
+ Element* b = GetElementById("b");
+ // <div>^foo<span>foof|<b>oo</b></span></div>
+ // So buffer = "foofoof"
+ FindBuffer buffer(EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*div->firstChild()),
+ PositionInFlatTree::LastPositionInNode(*span->firstChild())));
+ EXPECT_EQ(2u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("fo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("oof", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(4u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(3u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>f^oo<span>foof<b>o|o</b></span></div>
+ // So buffer = "oofoofo"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*div->firstChild(), 1),
+ PositionInFlatTree(*b->firstChild(), 1)));
+ EXPECT_EQ(1u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("oof", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("fo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(5u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>foo<span>f^oof|<b>oo</b></span></div>
+ // So buffer = "oof"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*span->firstChild(), 1),
+ PositionInFlatTree(*span->firstChild(), 4)));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oof", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("fo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>foo<span>foof^<b>oo|</b></span></div>
+ // So buffer = "oo"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*span->firstChild(), 4),
+ PositionInFlatTree(*b->firstChild(), 2)));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("oof", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("fo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, FindBetweenPositionsSkippedNodes) {
+ SetBodyContent(
+ "<div id='div'>foo<span id='span' style='display:none'>foof</span><b "
+ "id='b'>oo</b><script id='script'>fo</script><a id='a'>o</o></div>");
+ Element* div = GetElementById("div");
+ Element* span = GetElementById("span");
+ Element* b = GetElementById("b");
+ Element* script = GetElementById("script");
+ Element* a = GetElementById("a");
+
+ // <div>^foo<span style='display:none;'>foo|f</span><b>oo</b>
+ // <script>fo</script><a>o</a></div>
+ // So buffer = "foo"
+ FindBuffer buffer(EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*div->firstChild()),
+ PositionInFlatTree(*span->firstChild(), 3)));
+ EXPECT_EQ(1u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("oof", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("fo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>foo<span style='display:none;'>f^oof</span><b>oo|</b>
+ // <script>fo</script><a>o</a></div>
+ // So buffer = "oo"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*span->firstChild(), 1),
+ PositionInFlatTree(*b->firstChild(), 2)));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>foo<span style='display:none;'>f^oof</span><b>oo|</b>
+ // <script>f|o</script><a>o</a></div>
+ // So buffer = "oo"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*span->firstChild(), 1),
+ PositionInFlatTree(*script->firstChild(), 2)));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(2u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+ // <div>foo<span style='display:none;'>foof</span><b>oo|</b>
+ // <script>f^o</script><a>o|</a></div>
+ // So buffer = "o"
+ buffer = FindBuffer(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*script->firstChild(), 1),
+ PositionInFlatTree(*a->firstChild(), 1)));
+ EXPECT_EQ(0u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("oo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("o", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("f", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, FindMatchInRange) {
+ SetBodyContent(
+ "<div id='div' invisible>foo<a id='a'>foof</a><b id='b'>oo</b></div>");
+ Element* div = GetElementById("div");
+ Element* a = GetElementById("a");
+ Element* b = GetElementById("b");
+ EphemeralRangeInFlatTree foo1 = EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*div->firstChild()),
+ PositionInFlatTree::LastPositionInNode(*div->firstChild()));
+ EphemeralRangeInFlatTree foo2 = EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*a->firstChild()),
+ PositionInFlatTree(*a->firstChild(), 3));
+ EphemeralRangeInFlatTree foo3 = EphemeralRangeInFlatTree(
+ PositionInFlatTree(*a->firstChild(), 3),
+ PositionInFlatTree::LastPositionInNode(*b->firstChild()));
+
+ // <div>^foo<a>foof</a><b>oo|</b></div>, forwards
+ EphemeralRangeInFlatTree match = FindBuffer::FindMatchInRange(
+ WholeDocumentRange(), "foo", kCaseInsensitive);
+ EXPECT_EQ(foo1, match);
+ // <div>f^oo<a>foof</a><b>oo|</b></div>, forwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*div->firstChild(), 1),
+ LastPositionInDocument()),
+ "foo", kCaseInsensitive);
+ EXPECT_EQ(foo2, match);
+ // <div>foo<a>^foo|f</a><b>oo</b></div>, forwards
+ match = FindBuffer::FindMatchInRange(foo2, "foo", kCaseInsensitive);
+ EXPECT_EQ(foo2, match);
+ // <div>foo<a>f^oof|</a><b>oo</b></div>, forwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(
+ PositionInFlatTree(*a->firstChild(), 1),
+ PositionInFlatTree::LastPositionInNode(*a->firstChild())),
+ "foo", kCaseInsensitive);
+ EXPECT_TRUE(match.IsNull());
+ // <div>foo<a>f^oof</a><b>oo|</b></div>, forwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*a->firstChild(), 1),
+ LastPositionInDocument()),
+ "foo", kCaseInsensitive);
+ EXPECT_EQ(foo3, match);
+
+ // <div>^foo<a>foof</a><b>oo|</b></div>, backwards
+ match = FindBuffer::FindMatchInRange(WholeDocumentRange(), "foo",
+ kCaseInsensitive | kBackwards);
+ EXPECT_EQ(foo3, match);
+ // <div>^foo<a>foof</a><b>o|o</b></div>, backwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*div->firstChild()),
+ PositionInFlatTree(*b->firstChild(), 1)),
+ "foo", kCaseInsensitive | kBackwards);
+ EXPECT_EQ(foo2, match);
+ // <div>foo<a>^foof</a><b>o|o</b></div>, backwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*a->firstChild()),
+ PositionInFlatTree(*b->firstChild(), 1)),
+ "foo", kCaseInsensitive | kBackwards);
+ EXPECT_EQ(foo2, match);
+ // <div>foo<a>foo^f</a><b>o|o</b></div>, backwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(PositionInFlatTree(*a->firstChild(), 3),
+ PositionInFlatTree(*b->firstChild(), 1)),
+ "foo", kCaseInsensitive | kBackwards);
+ EXPECT_TRUE(match.IsNull());
+ // <div>^foo<a>fo|of</a><b>oo</b></div>, backwards
+ match = FindBuffer::FindMatchInRange(
+ EphemeralRangeInFlatTree(
+ PositionInFlatTree::FirstPositionInNode(*div->firstChild()),
+ PositionInFlatTree(*a->firstChild(), 2)),
+ "foo", kCaseInsensitive | kBackwards);
+ EXPECT_EQ(foo1, match);
+}
+
class FindBufferBlockTest : public FindBufferTest,
public testing::WithParamInterface<std::string> {};
-INSTANTIATE_TEST_CASE_P(Blocks,
- FindBufferBlockTest,
- testing::Values("block",
- "table",
- "flow-root",
- "grid",
- "flex",
- "list-item"));
+INSTANTIATE_TEST_SUITE_P(Blocks,
+ FindBufferBlockTest,
+ testing::Values("block",
+ "table",
+ "flow-root",
+ "grid",
+ "flex",
+ "list-item"));
TEST_P(FindBufferBlockTest, FindBlock) {
SetBodyContent("text<div id='block' style='display: " + GetParam() +
";'>block</div><span id='span'>span</span>");
- FindBuffer text_buffer(FirstPosition());
+ FindBuffer text_buffer(WholeDocumentRange());
EXPECT_EQ(GetElementById("block"),
*text_buffer.PositionAfterBlock().ComputeContainerNode());
- EXPECT_EQ(1u,
- text_buffer.FindMatches("text", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, text_buffer
- .FindMatches("textblock", *mojom::blink::FindOptions::New())
- ->CountForTesting());
EXPECT_EQ(
- 0u,
- text_buffer.FindMatches("text block", *mojom::blink::FindOptions::New())
- ->CountForTesting());
+ 1u, text_buffer.FindMatches("text", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, text_buffer.FindMatches("textblock", kCaseInsensitive)
+ ->CountForTesting());
+ EXPECT_EQ(0u, text_buffer.FindMatches("text block", kCaseInsensitive)
+ ->CountForTesting());
- FindBuffer block_buffer(text_buffer.PositionAfterBlock());
+ FindBuffer block_buffer(EphemeralRangeInFlatTree(
+ text_buffer.PositionAfterBlock(), LastPositionInDocument()));
EXPECT_EQ(GetElementById("span"),
*block_buffer.PositionAfterBlock().ComputeContainerNode());
EXPECT_EQ(
- 1u, block_buffer.FindMatches("block", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, block_buffer
- .FindMatches("textblock", *mojom::blink::FindOptions::New())
+ 1u,
+ block_buffer.FindMatches("block", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, block_buffer.FindMatches("textblock", kCaseInsensitive)
->CountForTesting());
- EXPECT_EQ(
- 0u,
- block_buffer.FindMatches("text block", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, block_buffer
- .FindMatches("blockspan", *mojom::blink::FindOptions::New())
+ EXPECT_EQ(0u, block_buffer.FindMatches("text block", kCaseInsensitive)
+ ->CountForTesting());
+ EXPECT_EQ(0u, block_buffer.FindMatches("blockspan", kCaseInsensitive)
+ ->CountForTesting());
+ EXPECT_EQ(0u, block_buffer.FindMatches("block span", kCaseInsensitive)
->CountForTesting());
- EXPECT_EQ(
- 0u,
- block_buffer.FindMatches("block span", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- FindBuffer span_buffer(block_buffer.PositionAfterBlock());
+ FindBuffer span_buffer(EphemeralRangeInFlatTree(
+ block_buffer.PositionAfterBlock(), LastPositionInDocument()));
EXPECT_TRUE(span_buffer.PositionAfterBlock().IsNull());
- EXPECT_EQ(1u,
- span_buffer.FindMatches("span", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, span_buffer
- .FindMatches("blockspan", *mojom::blink::FindOptions::New())
- ->CountForTesting());
EXPECT_EQ(
- 0u,
- span_buffer.FindMatches("block span", *mojom::blink::FindOptions::New())
- ->CountForTesting());
+ 1u, span_buffer.FindMatches("span", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, span_buffer.FindMatches("blockspan", kCaseInsensitive)
+ ->CountForTesting());
+ EXPECT_EQ(0u, span_buffer.FindMatches("block span", kCaseInsensitive)
+ ->CountForTesting());
}
class FindBufferSeparatorTest
: public FindBufferTest,
public testing::WithParamInterface<std::string> {};
-INSTANTIATE_TEST_CASE_P(Separators,
- FindBufferSeparatorTest,
- testing::Values("br",
- "hr",
- "legend",
- "meter",
- "object",
- "progress",
- "select",
- "video"));
+INSTANTIATE_TEST_SUITE_P(Separators,
+ FindBufferSeparatorTest,
+ testing::Values("br",
+ "hr",
+ "legend",
+ "meter",
+ "object",
+ "progress",
+ "select",
+ "video"));
TEST_P(FindBufferSeparatorTest, FindSeparatedElements) {
SetBodyContent("a<" + GetParam() + ">a</" + GetParam() + ">a");
- FindBuffer buffer(FirstPosition());
- EXPECT_EQ(0u, buffer.FindMatches("aa", *mojom::blink::FindOptions::New())
- ->CountForTesting());
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(0u, buffer.FindMatches("aa", kCaseInsensitive)->CountForTesting());
}
TEST_F(FindBufferTest, WhiteSpaceCollapsingPreWrap) {
SetBodyContent(
" a \n b <b> c </b> d <span style='white-space: pre-wrap'> e "
"</span>");
- FindBuffer buffer(FirstPosition());
+ FindBuffer buffer(WholeDocumentRange());
EXPECT_EQ(
- 1u, buffer.FindMatches("a b c d e ", *mojom::blink::FindOptions::New())
- ->CountForTesting());
-};
+ 1u,
+ buffer.FindMatches("a b c d e ", kCaseInsensitive)->CountForTesting());
+}
TEST_F(FindBufferTest, WhiteSpaceCollapsingPre) {
SetBodyContent("<div style='white-space: pre;'>a \n b</div>");
- FindBuffer buffer(FirstPosition());
- EXPECT_EQ(1u, buffer.FindMatches("a", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(1u, buffer.FindMatches("b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("ab", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a\n b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a \nb", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a \n b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(1u, buffer.FindMatches("a", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("ab", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a\n b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a \nb", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a \n b", kCaseInsensitive)->CountForTesting());
}
TEST_F(FindBufferTest, WhiteSpaceCollapsingPreLine) {
SetBodyContent("<div style='white-space: pre-line;'>a \n b</div>");
- FindBuffer buffer(FirstPosition());
- EXPECT_EQ(1u, buffer.FindMatches("a", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(1u, buffer.FindMatches("b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("ab", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a b", *mojom::blink::FindOptions::New())
- ->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a \n b", *mojom::blink::FindOptions::New())
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(1u, buffer.FindMatches("a", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("ab", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a \n b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a\n b", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a \nb", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u,
+ buffer.FindMatches("a\nb", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, BidiTest) {
+ SetBodyContent("<bdo dir=rtl id=bdo>foo<span>bar</span></bdo>");
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(1u,
+ buffer.FindMatches("foobar", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, KanaSmallVsNormal) {
+ SetBodyContent("や"); // Normal-sized や
+ FindBuffer buffer(WholeDocumentRange());
+ // Should find normal-sized や
+ EXPECT_EQ(1u, buffer.FindMatches("や", kCaseInsensitive)->CountForTesting());
+ // Should not find smalll-sized ゃ
+ EXPECT_EQ(0u, buffer.FindMatches("ゃ", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, KanaDakuten) {
+ SetBodyContent("びゃ"); // Hiragana bya
+ FindBuffer buffer(WholeDocumentRange());
+ // Should find bi
+ EXPECT_EQ(1u, buffer.FindMatches("び", kCaseInsensitive)->CountForTesting());
+ // Should find smalll-sized ゃ
+ EXPECT_EQ(1u, buffer.FindMatches("ゃ", kCaseInsensitive)->CountForTesting());
+ // Should find bya
+ EXPECT_EQ(1u,
+ buffer.FindMatches("びゃ", kCaseInsensitive)->CountForTesting());
+ // Should not find hi
+ EXPECT_EQ(0u, buffer.FindMatches("ひ", kCaseInsensitive)->CountForTesting());
+ // Should not find pi
+ EXPECT_EQ(0u, buffer.FindMatches("ぴ", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, KanaHalfFull) {
+ // Should treat hiragana, katakana, half width katakana as the same.
+ // hiragana ra, half width katakana ki, full width katakana na
+ SetBodyContent("らキナ");
+ FindBuffer buffer(WholeDocumentRange());
+ // Should find katakana ra
+ EXPECT_EQ(1u, buffer.FindMatches("ラ", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("ラ", kCaseInsensitive)->CountForTesting());
+ // Should find hiragana & katakana ki
+ EXPECT_EQ(1u, buffer.FindMatches("き", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("キ", kCaseInsensitive)->CountForTesting());
+ // Should find hiragana & katakana na
+ EXPECT_EQ(1u, buffer.FindMatches("な", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("ナ", kCaseInsensitive)->CountForTesting());
+ // Should find whole word
+ EXPECT_EQ(1u,
+ buffer.FindMatches("らきな", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("ラキナ", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u,
+ buffer.FindMatches("ラキナ", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, WholeWordTest) {
+ SetBodyContent("foo bar foobar 六本木");
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(2u, buffer.FindMatches("foo", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("foo", kCaseInsensitive | kWholeWord)
->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a\n b", *mojom::blink::FindOptions::New())
+ EXPECT_EQ(2u, buffer.FindMatches("bar", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("bar", kCaseInsensitive | kWholeWord)
->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a \nb", *mojom::blink::FindOptions::New())
+ EXPECT_EQ(1u, buffer.FindMatches("六", kCaseInsensitive | kWholeWord)
->CountForTesting());
- EXPECT_EQ(0u, buffer.FindMatches("a\nb", *mojom::blink::FindOptions::New())
+ EXPECT_EQ(1u, buffer.FindMatches("本木", kCaseInsensitive | kWholeWord)
->CountForTesting());
}
-TEST_F(FindBufferTest, BidiTest) {
- SetBodyContent("<bdo dir=rtl id=bdo>foo<span>bar</span></bdo>");
- FindBuffer buffer(FirstPosition());
- EXPECT_EQ(1u, buffer.FindMatches("foobar", *mojom::blink::FindOptions::New())
- ->CountForTesting());
+TEST_F(FindBufferTest, KanaDecomposed) {
+ SetBodyContent("は ゛");
+ FindBuffer buffer(WholeDocumentRange());
+ EXPECT_EQ(0u, buffer.FindMatches("ば", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u,
+ buffer.FindMatches("は ゛", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(0u, buffer.FindMatches("バ ", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u,
+ buffer.FindMatches("ハ ゛", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u, buffer.FindMatches("ハ ゙", kCaseInsensitive)->CountForTesting());
+ EXPECT_EQ(1u,
+ buffer.FindMatches("ハ ゛", kCaseInsensitive)->CountForTesting());
+}
+
+TEST_F(FindBufferTest, FindPlainTextInvalidTarget1) {
+ static const char* body_content = "<div>foo bar test</div>";
+ SetBodyContent(body_content);
+
+ // A lone lead surrogate (0xDA0A) example taken from fuzz-58.
+ static const UChar kInvalid1[] = {0x1461u, 0x2130u, 0x129bu, 0xd711u, 0xd6feu,
+ 0xccadu, 0x7064u, 0xd6a0u, 0x4e3bu, 0x03abu,
+ 0x17dcu, 0xb8b7u, 0xbf55u, 0xfca0u, 0x07fau,
+ 0x0427u, 0xda0au, 0};
+
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches(String(kInvalid1), 0);
+ EXPECT_TRUE(results->IsEmpty());
+}
+
+TEST_F(FindBufferTest, FindPlainTextInvalidTarget2) {
+ static const char* body_content = "<div>foo bar test</div>";
+ SetBodyContent(body_content);
+
+ // A lone trailing surrogate (U+DC01).
+ static const UChar kInvalid2[] = {0x1461u, 0x2130u, 0x129bu, 0xdc01u,
+ 0xd6feu, 0xccadu, 0};
+
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches(String(kInvalid2), 0);
+ EXPECT_TRUE(results->IsEmpty());
+}
+
+TEST_F(FindBufferTest, FindPlainTextInvalidTarget3) {
+ static const char* body_content = "<div>foo bar test</div>";
+ SetBodyContent(body_content);
+
+ // A trailing surrogate followed by a lead surrogate (U+DC03 U+D901).
+ static const UChar kInvalid3[] = {0xd800u, 0xdc00u, 0x0061u, 0xdc03u,
+ 0xd901u, 0xccadu, 0};
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches(String(kInvalid3), 0);
+ EXPECT_TRUE(results->IsEmpty());
+}
+
+TEST_F(FindBufferTest, DisplayInline) {
+ SetBodyContent("<span>fi</span>nd");
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches("find", 0);
+ ASSERT_EQ(1u, results->CountForTesting());
+ EXPECT_EQ(FindBuffer::BufferMatchResult({0, 4}), results->front());
+}
+
+TEST_F(FindBufferTest, DisplayBlock) {
+ SetBodyContent("<div>fi</div>nd");
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches("find", 0);
+ ASSERT_EQ(0u, results->CountForTesting())
+ << "We should not match across block.";
+}
+
+TEST_F(FindBufferTest, DisplayContents) {
+ SetBodyContent("<div style='display: contents'>fi</div>nd");
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches("find", 0);
+ ASSERT_EQ(1u, results->CountForTesting());
+ EXPECT_EQ(FindBuffer::BufferMatchResult({0, 4}), results->front());
+}
+
+TEST_F(FindBufferTest, WBRTest) {
+ SetBodyContent("fi<wbr>nd and fin<wbr>d");
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches("find", 0);
+ ASSERT_EQ(2u, results->CountForTesting());
+}
+
+TEST_F(FindBufferTest, InputTest) {
+ SetBodyContent("fi<input type='text'>nd and fin<input type='text'>d");
+ FindBuffer buffer(WholeDocumentRange());
+ const auto results = buffer.FindMatches("find", 0);
+ ASSERT_EQ(0u, results->CountForTesting());
+}
+
+TEST_F(FindBufferTest, SelectMultipleTest) {
+ SetBodyContent("<select multiple><option>find me</option></select>");
+ FindBuffer buffer(WholeDocumentRange());
+#if defined(OS_ANDROID)
+ EXPECT_EQ(0u, buffer.FindMatches("find", 0)->CountForTesting());
+#else
+ EXPECT_EQ(1u, buffer.FindMatches("find", 0)->CountForTesting());
+#endif // defined(OS_ANDROID)
+ SetBodyContent("<select size=2><option>find me</option></select>");
+ buffer = FindBuffer(WholeDocumentRange());
+#if defined(OS_ANDROID)
+ EXPECT_EQ(0u, buffer.FindMatches("find", 0)->CountForTesting());
+#else
+ EXPECT_EQ(1u, buffer.FindMatches("find", 0)->CountForTesting());
+#endif // defined(OS_ANDROID)
+ SetBodyContent("<select size=1><option>find me</option></select>");
+ buffer = FindBuffer(WholeDocumentRange());
+ EXPECT_EQ(0u, buffer.FindMatches("find", 0)->CountForTesting());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
index 76ecb45df78..c334cd8675f 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_in_page_coordinates.cc
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
+#include "third_party/blink/renderer/core/editing/visible_units.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
@@ -147,8 +148,8 @@ FloatRect FindInPageRectFromRange(const EphemeralRange& range) {
if (!baseLayoutObject)
return FloatRect();
- return FindInPageRectFromAbsoluteRect(
- LayoutObject::AbsoluteBoundingBoxRectForRange(range), baseLayoutObject);
+ return FindInPageRectFromAbsoluteRect(ComputeTextFloatRect(range),
+ baseLayoutObject);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
index 67736f9c97c..80b67e74787 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.cc
@@ -84,10 +84,16 @@ class FindTaskController::IdleFindTask
TimeDelta::FromMillisecondsD(deadline->timeRemaining());
const TimeTicks start_time = CurrentTimeTicks();
- PositionInFlatTree search_start = PositionInFlatTree::FirstPositionInNode(
- *controller_->GetLocalFrame()->GetDocument());
- PositionInFlatTree search_end = PositionInFlatTree::LastPositionInNode(
- *controller_->GetLocalFrame()->GetDocument());
+ Document& document = *controller_->GetLocalFrame()->GetDocument();
+ PositionInFlatTree search_start =
+ PositionInFlatTree::FirstPositionInNode(document);
+ PositionInFlatTree search_end;
+ if (document.documentElement() && document.documentElement()->lastChild()) {
+ search_end = PositionInFlatTree::AfterNode(
+ *document.documentElement()->lastChild());
+ } else {
+ search_end = PositionInFlatTree::LastPositionInNode(document);
+ }
DCHECK_EQ(search_start.GetDocument(), search_end.GetDocument());
if (Range* resume_from_range = controller_->ResumeFindingFromRange()) {
@@ -107,11 +113,17 @@ class FindTaskController::IdleFindTask
int match_count = 0;
bool full_range_searched = false;
PositionInFlatTree next_task_start_position;
- do {
+
+ blink::FindOptions find_options =
+ (options_->forward ? 0 : kBackwards) |
+ (options_->match_case ? 0 : kCaseInsensitive) |
+ (options_->find_next ? 0 : kStartInSelection);
+
+ while (search_start != search_end) {
// Find in the whole block.
- FindBuffer buffer(search_start);
+ FindBuffer buffer(EphemeralRangeInFlatTree(search_start, search_end));
std::unique_ptr<FindBuffer::Results> match_results =
- buffer.FindMatches(search_text_, *options_);
+ buffer.FindMatches(search_text_, find_options);
for (FindBuffer::BufferMatchResult match : *match_results) {
const EphemeralRangeInFlatTree ephemeral_match_range =
buffer.RangeFromBufferIndex(match.start,
@@ -138,7 +150,9 @@ class FindTaskController::IdleFindTask
break;
}
next_task_start_position = search_start;
- } while (deadline->timeRemaining() > 0);
+ if (deadline->timeRemaining() <= 0)
+ break;
+ }
const TimeDelta time_spent = CurrentTimeTicks() - start_time;
UMA_HISTOGRAM_TIMES("WebCore.FindInPage.ScopingTime",
@@ -287,4 +301,8 @@ void FindTaskController::Trace(Visitor* visitor) {
visitor->Trace(resume_finding_from_range_);
}
+void FindTaskController::ResetLastFindRequestCompletedWithNoMatches() {
+ last_find_request_completed_with_no_matches_ = false;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
index 1b99f852f8b..327d0348af8 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/find_task_controller.h
@@ -76,6 +76,8 @@ class CORE_EXPORT FindTaskController final
void Trace(Visitor* visitor);
+ void ResetLastFindRequestCompletedWithNoMatches();
+
private:
void RequestIdleFindTask(int identifier,
const WebString& search_text,
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 1f9438e77b9..fc7190494ff 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/editing/editor.h"
@@ -54,6 +55,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/invisible_dom/invisible_dom.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
@@ -67,12 +69,19 @@ namespace blink {
TextFinder::FindMatch::FindMatch(Range* range, int ordinal)
: range_(range), ordinal_(ordinal) {}
-void TextFinder::FindMatch::Trace(blink::Visitor* visitor) {
+void TextFinder::FindMatch::Trace(Visitor* visitor) {
visitor->Trace(range_);
}
static void ScrollToVisible(Range* match) {
const Node& first_node = *match->FirstNode();
+ if (RuntimeEnabledFeatures::InvisibleDOMEnabled() ||
+ RuntimeEnabledFeatures::DisplayLockingEnabled()) {
+ const EphemeralRangeInFlatTree range(match);
+ if (InvisibleDOM::ActivateRangeIfNeeded(range) ||
+ DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range))
+ first_node.GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
+ }
Settings* settings = first_node.GetDocument().GetSettings();
bool smooth_find_enabled =
settings ? settings->GetSmoothScrollForFindEnabled() : false;
@@ -156,8 +165,7 @@ bool TextFinder::Find(int identifier,
->PageNeedsAutosizing()) {
OwnerFrame().LocalRoot()->FrameWidget()->ZoomToFindInPageRect(
OwnerFrame().GetFrameView()->ConvertToRootFrame(
- EnclosingIntRect(LayoutObject::AbsoluteBoundingBoxRectForRange(
- EphemeralRange(active_match_.Get())))));
+ ComputeTextRect(EphemeralRange(active_match_.Get()))));
}
bool was_active_frame = current_active_match_frame_;
@@ -204,7 +212,7 @@ bool TextFinder::Find(int identifier,
}
// We found something, so the result of the previous scoping may be outdated.
- last_find_request_completed_with_no_matches_ = false;
+ find_task_controller_->ResetLastFindRequestCompletedWithNoMatches();
return true;
}
@@ -320,8 +328,8 @@ void TextFinder::ReportFindInPageResultToAccessibility(int identifier) {
if (!active_match_)
return;
- AXObjectCacheBase* ax_object_cache = ToAXObjectCacheBase(
- OwnerFrame().GetFrame()->GetDocument()->ExistingAXObjectCache());
+ auto* ax_object_cache =
+ OwnerFrame().GetFrame()->GetDocument()->ExistingAXObjectCache();
if (!ax_object_cache)
return;
@@ -607,8 +615,7 @@ int TextFinder::SelectFindMatch(unsigned index, WebRect* selection_rect) {
IntRect active_match_rect;
IntRect active_match_bounding_box =
- EnclosingIntRect(LayoutObject::AbsoluteBoundingBoxRectForRange(
- EphemeralRange(active_match_.Get())));
+ ComputeTextRect(EphemeralRange(active_match_.Get()));
if (!active_match_bounding_box.IsEmpty()) {
if (active_match_->FirstNode() &&
@@ -628,8 +635,7 @@ int TextFinder::SelectFindMatch(unsigned index, WebRect* selection_rect) {
// that needs to be merged to a release branch.
// https://crbug.com/823365.
active_match_bounding_box =
- EnclosingIntRect(LayoutObject::AbsoluteBoundingBoxRectForRange(
- EphemeralRange(active_match_.Get())));
+ ComputeTextRect(EphemeralRange(active_match_.Get()));
}
// Zoom to the active match.
@@ -661,7 +667,6 @@ TextFinder::TextFinder(WebLocalFrameImpl& owner_frame)
find_match_markers_version_(0),
should_locate_active_rect_(false),
scoping_in_progress_(false),
- last_find_request_completed_with_no_matches_(false),
find_match_rects_are_valid_(false) {}
TextFinder::~TextFinder() = default;
@@ -712,7 +717,7 @@ void TextFinder::InvalidatePaintForTickmarks() {
OwnerFrame().GetFrame()->ContentLayoutObject()->InvalidatePaintForTickmarks();
}
-void TextFinder::Trace(blink::Visitor* visitor) {
+void TextFinder::Trace(Visitor* visitor) {
visitor->Trace(owner_frame_);
visitor->Trace(find_task_controller_);
visitor->Trace(active_match_);
diff --git a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
index 3c3b9ab0001..38a250a2ab0 100644
--- a/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
+++ b/chromium/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -130,7 +130,7 @@ class CORE_EXPORT TextFinder final
public:
FindMatch(Range*, int ordinal);
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
Member<Range> range_;
@@ -142,7 +142,7 @@ class CORE_EXPORT TextFinder final
FloatRect rect_;
};
- void Trace(blink::Visitor*);
+ void Trace(Visitor*);
private:
// Notifies the delegate about a new selection rect.
@@ -240,10 +240,6 @@ class CORE_EXPORT TextFinder final
// Keeps track of whether there is an scoping effort ongoing in the frame.
bool scoping_in_progress_;
- // Keeps track of whether the last find request completed its scoping effort
- // without finding any matches in this frame.
- bool last_find_request_completed_with_no_matches_;
-
// Determines if the rects in the find-in-page matches cache of this frame
// are invalid and should be recomputed.
bool find_match_rects_are_valid_;
@@ -253,6 +249,6 @@ class CORE_EXPORT TextFinder final
} // namespace blink
-WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch);
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::TextFinder::FindMatch)
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_FINDER_TEXT_FINDER_H_