summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2017-04-27 11:23:55 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-02-25 10:43:19 +0100
commit90a9390416d1e4f8409e939e83e005119fdfe1a3 (patch)
treebabe471c0f4225d84191508fa447ce46a9b5d3e5
parent7fbf778631c9e0cc310106c6d2b35c811edcb8ec (diff)
downloadqtwebengine-chromium-90a9390416d1e4f8409e939e83e005119fdfe1a3.tar.gz
Update TextSelection for non-user initiated events
This makes Chromium Content API to be able to notify about text selection changes triggered by non-user events (eg. JavaScript, IME, autofill). Based on: https://codereview.chromium.org/2903833002 Corresponding Chromium bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=671986 Change-Id: I86a7f203d789853199469b301facd06fe5ba54bd Task-number: QTBUG-53134 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
-rw-r--r--chromium/content/browser/renderer_host/render_frame_host_impl.cc5
-rw-r--r--chromium/content/browser/renderer_host/render_frame_host_impl.h3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc9
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.cc3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.cc6
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.h3
-rw-r--r--chromium/content/browser/renderer_host/text_input_manager.cc9
-rw-r--r--chromium/content/browser/renderer_host/text_input_manager.h11
-rw-r--r--chromium/content/public/renderer/render_frame.h3
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc2
-rw-r--r--chromium/content/renderer/render_frame_impl.cc89
-rw-r--r--chromium/content/renderer/render_frame_impl.h5
-rw-r--r--chromium/pdf/pdf_view_web_plugin.cc2
-rw-r--r--chromium/third_party/blink/public/mojom/frame/frame.mojom3
-rw-r--r--chromium/third_party/blink/public/web/web_local_frame.h3
-rw-r--r--chromium/third_party/blink/public/web/web_local_frame_client.h2
-rw-r--r--chromium/third_party/blink/public/web/web_widget.h2
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.h3
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h1
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/widget/widget_base.cc2
30 files changed, 145 insertions, 67 deletions
diff --git a/chromium/content/browser/renderer_host/render_frame_host_impl.cc b/chromium/content/browser/renderer_host/render_frame_host_impl.cc
index e074c1317d9..1005687a68a 100644
--- a/chromium/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6138,9 +6138,10 @@ void RenderFrameHostImpl::FocusedElementChanged(
void RenderFrameHostImpl::TextSelectionChanged(const std::u16string& text,
uint32_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
has_selection_ = !text.empty();
- GetRenderWidgetHost()->SelectionChanged(text, offset, range);
+ GetRenderWidgetHost()->SelectionChanged(text, offset, range, user_initiated);
}
void RenderFrameHostImpl::DidReceiveUserActivation() {
diff --git a/chromium/content/browser/renderer_host/render_frame_host_impl.h b/chromium/content/browser/renderer_host/render_frame_host_impl.h
index dde52d4207f..662f6cdac81 100644
--- a/chromium/content/browser/renderer_host/render_frame_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_frame_host_impl.h
@@ -2078,7 +2078,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
blink::mojom::FocusType focus_type) override;
void TextSelectionChanged(const std::u16string& text,
uint32_t offset,
- const gfx::Range& range) override;
+ const gfx::Range& range,
+ bool user_initiated) override;
void ShowPopupMenu(
mojo::PendingRemote<blink::mojom::PopupMenuClient> popup_client,
const gfx::Rect& bounds,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
index 367c1795213..140f05001ec 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2181,9 +2181,12 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser(
void RenderWidgetHostImpl::SelectionChanged(const std::u16string& text,
uint32_t offset,
- const gfx::Range& range) {
- if (view_)
- view_->SelectionChanged(text, static_cast<size_t>(offset), range);
+ const gfx::Range& range,
+ bool user_initiated) {
+ if (view_) {
+ view_->SelectionChanged(text, static_cast<size_t>(offset), range,
+ user_initiated);
+ }
}
void RenderWidgetHostImpl::SelectionBoundsChanged(
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h
index da4223e064f..cfc49170b71 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -714,7 +714,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Called from a RenderFrameHost when the text selection has changed.
void SelectionChanged(const std::u16string& text,
uint32_t offset,
- const gfx::Range& range);
+ const gfx::Range& range,
+ bool user_initiated);
size_t in_flight_event_count() const { return in_flight_event_count_; }
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
index 9bbfba2c8a3..743014e51f2 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2740,7 +2740,8 @@ void RenderWidgetHostViewAura::OnTextSelectionChanged(
ui::ClipboardBuffer::kSelection)) {
const TextInputManager::TextSelection* selection =
GetTextInputManager()->GetTextSelection(focused_view);
- if (selection->selected_text().length()) {
+ if (selection->selected_text().length()
+ && selection->user_initiated()) {
// Set the ClipboardBuffer::kSelection to the ui::Clipboard.
ui::ScopedClipboardWriter clipboard_writer(
ui::ClipboardBuffer::kSelection);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
index 0399fd10fff..8c59a7d1204 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -174,9 +174,11 @@ RenderWidgetHostViewBase* RenderWidgetHostViewBase::GetRootView() {
void RenderWidgetHostViewBase::SelectionChanged(const std::u16string& text,
size_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
if (GetTextInputManager())
- GetTextInputManager()->SelectionChanged(this, text, offset, range);
+ GetTextInputManager()->SelectionChanged(this, text, offset, range,
+ user_initiated);
}
gfx::Size RenderWidgetHostViewBase::GetRequestedRendererSize() {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
index 7759ce1982e..897bcfa08df 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
@@ -191,7 +191,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView {
// Notifies the View that the renderer text selection has changed.
virtual void SelectionChanged(const std::u16string& text,
size_t offset,
- const gfx::Range& range);
+ const gfx::Range& range,
+ bool user_initiated);
// The requested size of the renderer. May differ from GetViewBounds().size()
// when the view requires additional throttling.
diff --git a/chromium/content/browser/renderer_host/text_input_manager.cc b/chromium/content/browser/renderer_host/text_input_manager.cc
index aad1e66b6fd..cb6e35d1111 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.cc
+++ b/chromium/content/browser/renderer_host/text_input_manager.cc
@@ -366,9 +366,10 @@ void TextInputManager::ImeCompositionRangeChanged(
void TextInputManager::SelectionChanged(RenderWidgetHostViewBase* view,
const std::u16string& text,
size_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
DCHECK(IsRegistered(view));
- text_selection_map_[view].SetSelection(text, offset, range);
+ text_selection_map_[view].SetSelection(text, offset, range, user_initiated);
for (auto& observer : observer_list_)
observer.OnTextSelectionChanged(this, view);
}
@@ -460,11 +461,13 @@ TextInputManager::TextSelection::~TextSelection() = default;
void TextInputManager::TextSelection::SetSelection(const std::u16string& text,
size_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
text_ = text;
range_.set_start(range.start());
range_.set_end(range.end());
offset_ = offset;
+ user_initiated_ = user_initiated;
// Update the selected text.
selected_text_.clear();
diff --git a/chromium/content/browser/renderer_host/text_input_manager.h b/chromium/content/browser/renderer_host/text_input_manager.h
index 83825478d72..6bc25d79472 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.h
+++ b/chromium/content/browser/renderer_host/text_input_manager.h
@@ -111,12 +111,14 @@ class CONTENT_EXPORT TextInputManager {
void SetSelection(const std::u16string& text,
size_t offset,
- const gfx::Range& range);
+ const gfx::Range& range,
+ bool user_initiated);
const std::u16string& selected_text() const { return selected_text_; }
size_t offset() const { return offset_; }
const gfx::Range& range() const { return range_; }
const std::u16string& text() const { return text_; }
+ bool user_initiated() const { return user_initiated_; }
private:
// The offset of the text stored in |text| relative to the start of the web
@@ -135,6 +137,10 @@ class CONTENT_EXPORT TextInputManager {
// Part of the text on the page which includes the highlighted text plus
// possibly several characters before and after it.
std::u16string text_;
+
+ // True if text selection is triggered by user input.
+ bool user_initiated_ = false;
+
};
explicit TextInputManager(bool should_do_learning);
@@ -228,7 +234,8 @@ class CONTENT_EXPORT TextInputManager {
void SelectionChanged(RenderWidgetHostViewBase* view,
const std::u16string& text,
size_t offset,
- const gfx::Range& range);
+ const gfx::Range& range,
+ bool user_initiated);
// Registers the given |view| for tracking its TextInputState. This is called
// by any view which has updates in its TextInputState (whether tab's RWHV or
diff --git a/chromium/content/public/renderer/render_frame.h b/chromium/content/public/renderer/render_frame.h
index 7395d54aef7..c2b1568f148 100644
--- a/chromium/content/public/renderer/render_frame.h
+++ b/chromium/content/public/renderer/render_frame.h
@@ -222,7 +222,8 @@ class CONTENT_EXPORT RenderFrame : public IPC::Listener,
// Notifies the browser of text selection changes made.
virtual void SetSelectedText(const std::u16string& selection_text,
size_t offset,
- const gfx::Range& range) = 0;
+ const gfx::Range& range,
+ bool user_initiated) = 0;
// Adds |message| to the DevTools console.
virtual void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level,
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
index ec8f6dd50d7..722c0cd0176 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1287,7 +1287,7 @@ void PepperPluginInstanceImpl::SetSelectedText(
selected_text_ = selected_text;
gfx::Range range(0, selected_text.length());
- render_frame_->SetSelectedText(selected_text, 0, range);
+ render_frame_->SetSelectedText(selected_text, 0, range, true);
}
void PepperPluginInstanceImpl::SetLinkUnderCursor(const std::string& url) {
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index 89c2b46cfae..7a6a68dc4a1 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -2092,7 +2092,8 @@ void RenderFrameImpl::PepperSelectionChanged(
// We have no reason to believe the locally cached last synced selection is
// invalid so we do not need to force the update if it matches our last synced
// value.
- SyncSelectionIfRequired(blink::SyncCondition::kNotForced, false);
+ SyncSelectionIfRequired(blink::SyncCondition::kNotForced, false /* is_empty_selection */,
+ true /* user_initiated */);
}
#endif // BUILDFLAG(ENABLE_PLUGINS)
@@ -2485,9 +2486,11 @@ void RenderFrameImpl::PluginDidStopLoading() {
void RenderFrameImpl::SetSelectedText(const std::u16string& selection_text,
size_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
GetWebFrame()->TextSelectionChanged(WebString::FromUTF16(selection_text),
- static_cast<uint32_t>(offset), range);
+ static_cast<uint32_t>(offset), range,
+ user_initiated);
}
void RenderFrameImpl::AddMessageToConsole(
@@ -4263,10 +4266,20 @@ void RenderFrameImpl::AbortClientNavigation() {
void RenderFrameImpl::DidChangeSelection(bool is_empty_selection,
blink::SyncCondition force_sync) {
- if (!GetLocalRootWebFrameWidget()->HandlingInputEvent() &&
- !GetLocalRootWebFrameWidget()->HandlingSelectRange())
- return;
+ bool user_initiated =
+ GetLocalRootWebFrameWidget()->HandlingInputEvent() ||
+ GetLocalRootWebFrameWidget()->HandlingSelectRange();
+
+ if (!user_initiated) {
+ // Do not update text input state unnecessarily when text selection remains
+ // empty.
+ if (is_empty_selection && selection_text_.empty())
+ return;
+ // Ignore selection change of text replacement triggered by IME composition.
+ if (GetLocalRootWebFrameWidget()->ImeCompositionReplacement())
+ return;
+ }
// UpdateTextInputState should be called before SyncSelectionIfRequired.
// UpdateTextInputState may send TextInputStateChanged to notify the focus
@@ -4274,7 +4287,7 @@ void RenderFrameImpl::DidChangeSelection(bool is_empty_selection,
// to notify the selection was changed. Focus change should be notified
// before selection change.
GetLocalRootWebFrameWidget()->UpdateTextInputState();
- SyncSelectionIfRequired(force_sync, is_empty_selection);
+ SyncSelectionIfRequired(force_sync, is_empty_selection, user_initiated);
}
void RenderFrameImpl::OnMainFrameIntersectionChanged(
@@ -5641,10 +5654,12 @@ void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
GetFrameHost()->UpdateEncoding(encoding_name);
}
-void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection) {
+void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync,
+ bool is_empty_selection,
+ bool user_initiated) {
std::u16string text;
size_t offset = 0;
- gfx::Range range;
+ gfx::Range range = gfx::Range::InvalidRange();
#if BUILDFLAG(ENABLE_PLUGINS)
if (focused_pepper_plugin_) {
focused_pepper_plugin_->GetSurroundingText(&text, &range);
@@ -5655,31 +5670,37 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, b
if (!is_empty_selection) {
WebRange selection =
frame_->GetInputMethodController()->GetSelectionOffsets();
- if (selection.IsNull())
- return;
-
- range = gfx::Range(selection.StartOffset(), selection.EndOffset());
- if (frame_->GetInputMethodController()->TextInputType() !=
- blink::kWebTextInputTypeNone) {
- // If current focused element is editable, we will send 100 more chars
- // before and after selection. It is for input method surrounding text
- // feature.
- if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
- offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
- else
- offset = 0;
- size_t length =
- selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
- text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
- } else {
- offset = selection.StartOffset();
- text = frame_->SelectionAsText().Utf16();
- // http://crbug.com/101435
- // In some case, frame->selectionAsText() returned text's length is not
- // equal to the length returned from frame_->GetSelectionOffsets(). So we
- // have to set the range according to text.length().
- range.set_end(range.start() + text.length());
+ // When clearing text selection from JavaScript the selection range
+ // might be null but the selected text still have to be updated.
+ // Do not cancel sync selection if the clear was not user initiated.
+ if (!selection.IsNull()) {
+ range = gfx::Range(selection.StartOffset(), selection.EndOffset());
+
+ if (frame_->GetInputMethodController()->TextInputType() !=
+ blink::kWebTextInputTypeNone) {
+ // If current focused element is editable, we will send 100 more chars
+ // before and after selection. It is for input method surrounding text
+ // feature.
+ if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
+ offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
+ else
+ offset = 0;
+ size_t length =
+ selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
+ text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
+ } else {
+ offset = selection.StartOffset();
+ text = frame_->SelectionAsText().Utf16();
+ // http://crbug.com/101435
+ // In some case, frame->selectionAsText() returned text's length is not
+ // equal to the length returned from
+ // GetWebWidget()->caretOrSelectionRange().
+ // So we have to set the range according to text.length().
+ range.set_end(range.start() + text.length());
+ }
+ } else if (user_initiated) {
+ return;
}
}
@@ -5695,7 +5716,7 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync, b
selection_text_ = text;
selection_text_offset_ = offset;
selection_range_ = range;
- SetSelectedText(text, offset, range);
+ SetSelectedText(text, offset, range, user_initiated);
}
GetLocalRootWebFrameWidget()->UpdateSelectionBounds();
}
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index 7e006ca25de..e23816278d3 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -368,7 +368,8 @@ class CONTENT_EXPORT RenderFrameImpl
#endif
void SetSelectedText(const std::u16string& selection_text,
size_t offset,
- const gfx::Range& range) override;
+ const gfx::Range& range,
+ bool user_initiated) override;
void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level,
const std::string& message) override;
blink::PreviewsState GetPreviewsState() override;
@@ -633,7 +634,7 @@ class CONTENT_EXPORT RenderFrameImpl
// it has changed or if the forced flag is passed. The forced flag is used
// when the browser selection may be out of sync with the renderer due to
// incorrect prediction.
- void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection) override;
+ void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool is_empty_selection, bool user_initiated) override;
void CreateAudioInputStream(
blink::CrossVariantMojoRemote<
blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase>
diff --git a/chromium/pdf/pdf_view_web_plugin.cc b/chromium/pdf/pdf_view_web_plugin.cc
index aa50cccff71..1aca19f2e63 100644
--- a/chromium/pdf/pdf_view_web_plugin.cc
+++ b/chromium/pdf/pdf_view_web_plugin.cc
@@ -223,7 +223,7 @@ class BlinkContainerWrapper final : public PdfViewWebPlugin::ContainerWrapper {
blink::WebLocalFrame* frame = GetFrame();
frame->View()->SetFocusedFrame(frame);
- frame->TextSelectionChanged(selection_text, offset, range);
+ frame->TextSelectionChanged(selection_text, offset, range, /* user_initiated = */true);
}
std::unique_ptr<blink::WebAssociatedURLLoader> CreateAssociatedURLLoader(
diff --git a/chromium/third_party/blink/public/mojom/frame/frame.mojom b/chromium/third_party/blink/public/mojom/frame/frame.mojom
index 19c639bf81e..a40939d9b54 100644
--- a/chromium/third_party/blink/public/mojom/frame/frame.mojom
+++ b/chromium/third_party/blink/public/mojom/frame/frame.mojom
@@ -439,7 +439,8 @@ interface LocalFrameHost {
// std::u16string text in the document.
TextSelectionChanged(mojo_base.mojom.BigString16 text,
uint32 offset,
- gfx.mojom.Range range);
+ gfx.mojom.Range range,
+ bool user_initiated);
// Show a popup menu using native controls on Mac or Android.
// The popup menu is hidden when the mojo channel is closed.
diff --git a/chromium/third_party/blink/public/web/web_local_frame.h b/chromium/third_party/blink/public/web/web_local_frame.h
index a6b928747c6..6c79dbc68b0 100644
--- a/chromium/third_party/blink/public/web/web_local_frame.h
+++ b/chromium/third_party/blink/public/web/web_local_frame.h
@@ -500,7 +500,8 @@ class WebLocalFrame : public WebFrame {
virtual void TextSelectionChanged(const WebString& selection_text,
uint32_t offset,
- const gfx::Range& range) = 0;
+ const gfx::Range& range,
+ bool user_initiated) = 0;
// DEPRECATED: Use moveRangeSelection.
virtual void SelectRange(const gfx::Point& base,
diff --git a/chromium/third_party/blink/public/web/web_local_frame_client.h b/chromium/third_party/blink/public/web/web_local_frame_client.h
index 88cdfd93be4..a54eb0499ba 100644
--- a/chromium/third_party/blink/public/web/web_local_frame_client.h
+++ b/chromium/third_party/blink/public/web/web_local_frame_client.h
@@ -729,7 +729,7 @@ class BLINK_EXPORT WebLocalFrameClient {
// TextInputState may have changed call DidChangeSelection instead.
// If the browser selection may not match the last synced
// value, SyncCondition::kForced can be passed to force a sync.
- virtual void SyncSelectionIfRequired(SyncCondition force_sync, bool is_empty_selection) {}
+ virtual void SyncSelectionIfRequired(SyncCondition force_sync, bool is_empty_selection, bool user_initiated) {}
// TODO(https://crbug.com/787252): Remove the methods below and use the
// Supplement mechanism.
diff --git a/chromium/third_party/blink/public/web/web_widget.h b/chromium/third_party/blink/public/web/web_widget.h
index 0f70b5d492e..602b579dd47 100644
--- a/chromium/third_party/blink/public/web/web_widget.h
+++ b/chromium/third_party/blink/public/web/web_widget.h
@@ -153,6 +153,8 @@ class WebWidget {
// Set state that the widget is in the process of handling input events.
virtual void SetHandlingInputEvent(bool handling) = 0;
+ virtual bool ImeCompositionReplacement() = 0;
+
// Process the input event, blocking until complete.
virtual void ProcessInputEventSynchronouslyForTesting(
const WebCoalescedInputEvent&) = 0;
diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index 87720e55dbb..683e3d162a6 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -479,6 +479,10 @@ void WebPagePopupImpl::SetHandlingInputEvent(bool handling) {
widget_base_->input_handler().set_handling_input_event(handling);
}
+bool WebPagePopupImpl::ImeCompositionReplacement() {
+ return widget_base_->input_handler().ime_composition_replacement();
+}
+
void WebPagePopupImpl::ProcessInputEventSynchronouslyForTesting(
const WebCoalescedInputEvent& event) {
widget_base_->input_handler().HandleInputEvent(event, nullptr,
diff --git a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
index 7a326a1d482..96772094917 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -169,6 +169,7 @@ class CORE_EXPORT WebPagePopupImpl final : public WebPagePopup,
void SetCursor(const ui::Cursor& cursor) override;
bool HandlingInputEvent() override;
void SetHandlingInputEvent(bool handling) override;
+ bool ImeCompositionReplacement() override;
void ProcessInputEventSynchronouslyForTesting(
const WebCoalescedInputEvent&) override;
void UpdateTextInputState() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
index e4fa7685539..51e84d62055 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1382,8 +1382,9 @@ String LocalFrame::SelectedTextForClipboard() const {
void LocalFrame::TextSelectionChanged(const WTF::String& selection_text,
uint32_t offset,
- const gfx::Range& range) const {
- GetLocalFrameHostRemote().TextSelectionChanged(selection_text, offset, range);
+ const gfx::Range& range,
+ bool user_initiated) const {
+ GetLocalFrameHostRemote().TextSelectionChanged(selection_text, offset, range, user_initiated);
}
PositionWithAffinity LocalFrame::PositionForPoint(
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h
index b52d6d575fc..2770f007523 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -365,7 +365,8 @@ class CORE_EXPORT LocalFrame final
String SelectedTextForClipboard() const;
void TextSelectionChanged(const WTF::String& selection_text,
uint32_t offset,
- const gfx::Range& range) const;
+ const gfx::Range& range,
+ bool user_initiated) const;
PositionWithAffinityTemplate<EditingAlgorithm<NodeTraversal>>
PositionForPoint(const PhysicalOffset& frame_point);
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index 2bba71833d6..da796cf0860 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -2400,6 +2400,11 @@ void WebFrameWidgetImpl::SetHandlingInputEvent(bool handling) {
widget_base_->input_handler().set_handling_input_event(handling);
}
+bool WebFrameWidgetImpl::ImeCompositionReplacement()
+{
+ return widget_base_->input_handler().ime_composition_replacement();
+}
+
void WebFrameWidgetImpl::ProcessInputEventSynchronouslyForTesting(
const WebCoalescedInputEvent& event,
WidgetBaseInputHandler::HandledEventCallback callback) {
@@ -3593,7 +3598,8 @@ void WebFrameWidgetImpl::Replace(const String& word) {
// If the resulting selection is not actually a change in selection, we do not
// need to explicitly notify about the selection change.
focused_frame->Client()->SyncSelectionIfRequired(
- blink::SyncCondition::kNotForced);
+ blink::SyncCondition::kNotForced, false /* is_empty_selection */,
+ true /* user_initiated */);
}
void WebFrameWidgetImpl::ReplaceMisspelling(const String& word) {
diff --git a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index 9122fb0838e..0301c92547f 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -361,6 +361,7 @@ class CORE_EXPORT WebFrameWidgetImpl
void SetCursor(const ui::Cursor& cursor) override;
bool HandlingInputEvent() override;
void SetHandlingInputEvent(bool handling) override;
+ bool ImeCompositionReplacement() override;
void ProcessInputEventSynchronouslyForTesting(
const WebCoalescedInputEvent&) override;
WebInputEventResult DispatchBufferedTouchEvents() override;
diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 8cdd9af092a..780468a755e 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -1384,8 +1384,9 @@ WebString WebLocalFrameImpl::SelectionAsMarkup() const {
void WebLocalFrameImpl::TextSelectionChanged(const WebString& selection_text,
uint32_t offset,
- const gfx::Range& range) {
- GetFrame()->TextSelectionChanged(selection_text, offset, range);
+ const gfx::Range& range,
+ bool user_initiated) {
+ GetFrame()->TextSelectionChanged(selection_text, offset, range, user_initiated);
}
bool WebLocalFrameImpl::SelectAroundCaret(
diff --git a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index be3edad4ab9..a63ab7d21c0 100644
--- a/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/chromium/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -215,7 +215,8 @@ class CORE_EXPORT WebLocalFrameImpl final
WebString SelectionAsMarkup() const override;
void TextSelectionChanged(const WebString& selection_text,
uint32_t offset,
- const gfx::Range& range) override;
+ const gfx::Range& range,
+ bool);
bool SelectAroundCaret(mojom::blink::SelectionGranularity granularity,
bool should_show_handle,
bool should_show_context_menu);
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
index ae8e1bb2803..3df8d4264df 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
+++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -162,7 +162,8 @@ void FakeLocalFrameHost::FocusedElementChanged(
void FakeLocalFrameHost::TextSelectionChanged(const WTF::String& text,
uint32_t offset,
- const gfx::Range& range) {}
+ const gfx::Range& range,
+ bool user_initiated) {}
void FakeLocalFrameHost::ShowPopupMenu(
mojo::PendingRemote<mojom::blink::PopupMenuClient> popup_client,
const gfx::Rect& bounds,
diff --git a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
index f8b98bcb7da..59f1eafb64d 100644
--- a/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
+++ b/chromium/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -105,7 +105,8 @@ class FakeLocalFrameHost : public mojom::blink::LocalFrameHost {
blink::mojom::FocusType focus_type) override;
void TextSelectionChanged(const WTF::String& text,
uint32_t offset,
- const gfx::Range& range) override;
+ const gfx::Range& range,
+ bool user_initiated) override;
void ShowPopupMenu(
mojo::PendingRemote<mojom::blink::PopupMenuClient> popup_client,
const gfx::Rect& bounds,
diff --git a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h
index 426cc0e890f..8c083002abc 100644
--- a/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h
+++ b/chromium/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.h
@@ -90,6 +90,13 @@ class PLATFORM_EXPORT WidgetBaseInputHandler {
// cursor.
bool DidChangeCursor(const ui::Cursor& cursor);
+ bool ime_composition_replacement() const {
+ return ime_composition_replacement_;
+ }
+ void set_ime_composition_replacement(bool ime_composition_replacement) {
+ ime_composition_replacement_ = ime_composition_replacement;
+ }
+
private:
class HandlingState;
struct InjectScrollGestureParams {
@@ -137,6 +144,10 @@ class PLATFORM_EXPORT WidgetBaseInputHandler {
const bool supports_buffered_touch_ = false;
+ // Used to suppress notification about text selection changes triggered by
+ // IME composition when it replaces text.
+ bool ime_composition_replacement_ = false;
+
base::WeakPtrFactory<WidgetBaseInputHandler> weak_ptr_factory_{this};
};
diff --git a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
index 5c2a96b1458..bd88fc480ac 100644
--- a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -1248,6 +1248,7 @@ void WidgetBase::ImeSetComposition(
}
ImeEventGuard guard(weak_ptr_factory_.GetWeakPtr());
+ input_handler_.set_ime_composition_replacement(replacement_range.IsValid());
if (!frame_widget->SetComposition(text, ime_text_spans, replacement_range,
selection_start, selection_end)) {
// If we failed to set the composition text, then we need to let the browser
@@ -1258,6 +1259,7 @@ void WidgetBase::ImeSetComposition(
host->ImeCancelComposition();
}
}
+ input_handler_.set_ime_composition_replacement(false);
UpdateCompositionInfo(false /* not an immediate request */);
}