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>2021-10-04 10:21:13 +0200
commitd6f8fb4f7390cc52f8cd4a08b890bac77bc9c678 (patch)
tree7d52759901d0ebce67ba7d98a3f5e6e0eb03805f
parent040ca9ac423dbaead66b14b414a66b0ee143912f (diff)
downloadqtwebengine-chromium-d6f8fb4f7390cc52f8cd4a08b890bac77bc9c678.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.cc4
-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.h10
-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.cc91
-rw-r--r--chromium/content/renderer/render_frame_impl.h5
-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.cc7
-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
29 files changed, 144 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 c48863fc9c2..ed441caa5f3 100644
--- a/chromium/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5359,9 +5359,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 3456986091a..760ccc5c757 100644
--- a/chromium/content/browser/renderer_host/render_frame_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_frame_host_impl.h
@@ -1861,7 +1861,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 6a784277073..7b576ab127d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2139,9 +2139,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 bc4800b72f8..2c1a07c6daa 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -696,7 +696,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 b8ae3c5d06c..1cfec9cf5f1 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
@@ -2576,7 +2576,9 @@ 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 ec0d6b0acbc..b67a546bd65 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
@@ -176,9 +176,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 8cc591cfc75..f1739d6f84c 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
@@ -211,7 +211,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 707d5d7348f..b8eab6b746f 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.cc
+++ b/chromium/content/browser/renderer_host/text_input_manager.cc
@@ -340,9 +340,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);
}
@@ -431,11 +432,13 @@ TextInputManager::TextSelection::~TextSelection() {}
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 f1cc5560c1a..d7d887e8aef 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.h
+++ b/chromium/content/browser/renderer_host/text_input_manager.h
@@ -108,12 +108,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
@@ -132,6 +134,9 @@ 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);
@@ -215,7 +220,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 577f42d52e0..4a5fcfca191 100644
--- a/chromium/content/public/renderer/render_frame.h
+++ b/chromium/content/public/renderer/render_frame.h
@@ -215,7 +215,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 b43d23fce76..7b47dafa6d5 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1294,7 +1294,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 09cf0bc111e..12d0e63945e 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -1970,7 +1970,7 @@ 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);
+ SyncSelectionIfRequired(blink::SyncCondition::kNotForced, true /* user_initiated */);
}
#endif // BUILDFLAG(ENABLE_PLUGINS)
@@ -2357,9 +2357,11 @@ bool RenderFrameImpl::IsFTPDirectoryListing() {
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(
@@ -3967,20 +3969,32 @@ 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 (is_empty_selection)
selection_text_.clear();
+ if (!user_initiated) {
+ // Do not update text input state unnecessarily when text selection remains
+ // empty.
+ if (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
// was changed, and SyncSelectionIfRequired may send SelectionChanged
// to notify the selection was changed. Focus change should be notified
// before selection change.
GetLocalRootWebFrameWidget()->UpdateTextInputState();
- SyncSelectionIfRequired(force_sync);
+ SyncSelectionIfRequired(force_sync, user_initiated);
}
void RenderFrameImpl::OnMainFrameIntersectionChanged(
@@ -5297,10 +5311,11 @@ void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
GetFrameHost()->UpdateEncoding(encoding_name);
}
-void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) {
+void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync,
+ bool user_initiated) {
std::u16string text;
- size_t offset;
- gfx::Range range;
+ size_t offset = 0;
+ gfx::Range range = gfx::Range::InvalidRange();
#if BUILDFLAG(ENABLE_PLUGINS)
if (focused_pepper_plugin_) {
focused_pepper_plugin_->GetSurroundingText(&text, &range);
@@ -5311,31 +5326,37 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) {
{
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;
}
}
@@ -5351,7 +5372,7 @@ void RenderFrameImpl::SyncSelectionIfRequired(blink::SyncCondition force_sync) {
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 f659ea4833f..c5328328e6b 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -359,7 +359,8 @@ class CONTENT_EXPORT RenderFrameImpl
bool IsFTPDirectoryListing() override;
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;
@@ -610,7 +611,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) override;
+ void SyncSelectionIfRequired(blink::SyncCondition force_sync, bool user_initiated) override;
void CreateAudioInputStream(
blink::CrossVariantMojoRemote<
blink::mojom::RendererAudioInputStreamFactoryClientInterfaceBase>
diff --git a/chromium/third_party/blink/public/mojom/frame/frame.mojom b/chromium/third_party/blink/public/mojom/frame/frame.mojom
index 3bb95982889..fad36112e5a 100644
--- a/chromium/third_party/blink/public/mojom/frame/frame.mojom
+++ b/chromium/third_party/blink/public/mojom/frame/frame.mojom
@@ -433,7 +433,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 9b42baf6eb4..6929ab8ca64 100644
--- a/chromium/third_party/blink/public/web/web_local_frame.h
+++ b/chromium/third_party/blink/public/web/web_local_frame.h
@@ -476,7 +476,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;
// Expands the selection to a word around the caret and returns
// true. Does nothing and returns false if there is no caret or
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 c17f15d9cbf..ec423c3d29f 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
@@ -710,7 +710,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) {}
+ virtual void SyncSelectionIfRequired(SyncCondition force_sync, 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 190cc57ddbb..df5e4a8e17e 100644
--- a/chromium/third_party/blink/public/web/web_widget.h
+++ b/chromium/third_party/blink/public/web/web_widget.h
@@ -155,6 +155,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;
+
using HandledEventCallback = base::OnceCallback<void(
mojom::InputEventResultState ack_state,
const ui::LatencyInfo& latency_info,
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 bd6d49a8124..39e61aac2fa 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
@@ -475,6 +475,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,
HandledEventCallback callback) {
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 4e25100f681..1df5c11223e 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
@@ -167,6 +167,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&,
HandledEventCallback) 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 fab2d2cbc44..df8eafc11d3 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1605,8 +1605,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 777647d822d..ac2254f0de4 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.h
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h
@@ -360,7 +360,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 3dd4e255bd0..c41df9b6526 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
@@ -2328,6 +2328,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,
HandledEventCallback callback) {
@@ -3498,7 +3503,7 @@ 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, 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 3475cad430b..cec066aad5d 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
@@ -344,6 +344,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&,
HandledEventCallback) 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 dd4012a8dc0..6aa502cd702 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
@@ -1398,8 +1398,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::SelectWordAroundCaret() {
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 c722101236b..9be01605790 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
@@ -213,7 +213,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 user_initiated) override;
bool SelectWordAroundCaret() override;
void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
void SelectRange(const WebRange&,
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 70d0a8e83a8..7fa96978dcd 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
@@ -165,7 +165,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 674aa1836e9..cb21b2c131b 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 240c06a824a..de2b557db10 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 bcf11465aa1..dad08c26cfb 100644
--- a/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/chromium/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -1211,6 +1211,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
@@ -1221,6 +1222,7 @@ void WidgetBase::ImeSetComposition(
host->ImeCancelComposition();
}
}
+ input_handler_.set_ime_composition_replacement(false);
UpdateCompositionInfo(false /* not an immediate request */);
}