Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(696)

Unified Diff: content/renderer/render_frame_impl.cc

Issue 2903833002: Reland: Update TextSelection for non-user initiated events
Patch Set: Suppress superfluous non-user initiated text selection events Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/render_frame_impl.cc
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 901eb2261a0b4512b4db7645600e3a2c2d0b0864..740ca73cfcfce4f54db8d8bb6392b3194ba7a46f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1419,7 +1419,9 @@ void RenderFrameImpl::PepperSelectionChanged(
PepperPluginInstanceImpl* instance) {
if (instance != focused_pepper_plugin_)
return;
- SyncSelectionIfRequired();
+ // Keep the original behavior for pepper plugins and handle all selection
+ // change as user initiated.
Changwan Ryu 2017/07/14 18:44:03 I'm not too familiar with the pepper and desktop u
Peter Varga 2017/07/17 09:36:06 I'm also not familiar with pepper, that's why I ke
+ SyncSelectionIfRequired(true);
}
RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
@@ -2005,7 +2007,9 @@ void RenderFrameImpl::OnReplace(const base::string16& text) {
frame_->SelectWordAroundCaret();
frame_->ReplaceSelection(WebString::FromUTF16(text));
- SyncSelectionIfRequired();
+ // Handle this selection change as user initiated since typically triggered
+ // from context menu.
+ SyncSelectionIfRequired(true);
}
void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) {
@@ -2707,9 +2711,11 @@ void RenderFrameImpl::DetachGuest(int element_instance_id) {
void RenderFrameImpl::SetSelectedText(const base::string16& selection_text,
size_t offset,
- const gfx::Range& range) {
+ const gfx::Range& range,
+ bool user_initiated) {
Send(new FrameHostMsg_SelectionChanged(routing_id_, selection_text,
- static_cast<uint32_t>(offset), range));
+ static_cast<uint32_t>(offset), range,
+ user_initiated));
}
void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
@@ -4087,9 +4093,20 @@ void RenderFrameImpl::AbortClientNavigation() {
}
void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) {
- if (!GetRenderWidget()->input_handler().handling_input_event() &&
- !handling_select_range_)
- return;
+ bool user_initiated =
+ GetRenderWidget()->input_handler().handling_input_event() ||
+ handling_select_range_;
+
+ if (!user_initiated) {
+ // Do not update text input state unnecessarily when text selection remains
+ // empty.
+ if (is_empty_selection && selection_text_.empty())
Changwan Ryu 2017/07/14 18:44:03 What happens if move the cursor from one position
Peter Varga 2017/07/17 09:36:06 I assume you mean to change cursor position by emp
+ return;
+
+ // Ignore selection change of text replacement triggered by IME composition.
+ if (GetRenderWidget()->input_handler().ime_composition_replacement())
Changwan Ryu 2017/07/14 18:44:03 Hmm... This approach is quite brittle. SetComposin
EhsanK 2017/07/14 18:55:21 I think this is something worth pursing. The poten
Peter Varga 2017/07/17 09:36:06 I try to handle this in render_widget.cc. Only unn
+ return;
+ }
if (is_empty_selection)
selection_text_.clear();
@@ -4100,7 +4117,7 @@ void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) {
// to notify the selection was changed. Focus change should be notified
// before selection change.
GetRenderWidget()->UpdateTextInputState();
- SyncSelectionIfRequired();
+ SyncSelectionIfRequired(user_initiated);
}
bool RenderFrameImpl::HandleCurrentKeyboardEvent() {
@@ -6210,10 +6227,10 @@ void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name));
}
-void RenderFrameImpl::SyncSelectionIfRequired() {
+void RenderFrameImpl::SyncSelectionIfRequired(bool user_initiated) {
base::string16 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);
@@ -6224,32 +6241,37 @@ void RenderFrameImpl::SyncSelectionIfRequired() {
{
WebRange selection =
GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
- 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
- // GetWebWidget()->caretOrSelectionRange().
- // 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;
}
}
@@ -6265,7 +6287,7 @@ void RenderFrameImpl::SyncSelectionIfRequired() {
selection_text_ = text;
selection_text_offset_ = offset;
selection_range_ = range;
- SetSelectedText(text, offset, range);
+ SetSelectedText(text, offset, range, user_initiated);
}
GetRenderWidget()->UpdateSelectionBounds();
}

Powered by Google App Engine
This is Rietveld 408576698