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

Side by Side 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, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 #if defined(OS_MACOSX) || defined(USE_AURA) 1412 #if defined(OS_MACOSX) || defined(USE_AURA)
1413 GetRenderWidget()->UpdateCompositionInfo( 1413 GetRenderWidget()->UpdateCompositionInfo(
1414 false /* not an immediate request */); 1414 false /* not an immediate request */);
1415 #endif 1415 #endif
1416 } 1416 }
1417 1417
1418 void RenderFrameImpl::PepperSelectionChanged( 1418 void RenderFrameImpl::PepperSelectionChanged(
1419 PepperPluginInstanceImpl* instance) { 1419 PepperPluginInstanceImpl* instance) {
1420 if (instance != focused_pepper_plugin_) 1420 if (instance != focused_pepper_plugin_)
1421 return; 1421 return;
1422 SyncSelectionIfRequired(); 1422 // Keep the original behavior for pepper plugins and handle all selection
1423 // 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
1424 SyncSelectionIfRequired(true);
1423 } 1425 }
1424 1426
1425 RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer( 1427 RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
1426 PepperPluginInstanceImpl* plugin) { 1428 PepperPluginInstanceImpl* plugin) {
1427 GURL active_url; 1429 GURL active_url;
1428 if (render_view()->webview()) 1430 if (render_view()->webview())
1429 active_url = render_view()->GetURLForGraphicsContext3D(); 1431 active_url = render_view()->GetURLForGraphicsContext3D();
1430 1432
1431 // Synchronous IPC to obtain a routing id for the fullscreen widget. 1433 // Synchronous IPC to obtain a routing id for the fullscreen widget.
1432 int32_t fullscreen_widget_routing_id = MSG_ROUTING_NONE; 1434 int32_t fullscreen_widget_routing_id = MSG_ROUTING_NONE;
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 base::AutoReset<bool> handling_select_range(&handling_select_range_, true); 2000 base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
1999 frame_->MoveRangeSelectionExtent( 2001 frame_->MoveRangeSelectionExtent(
2000 render_view_->ConvertWindowPointToViewport(point)); 2002 render_view_->ConvertWindowPointToViewport(point));
2001 } 2003 }
2002 2004
2003 void RenderFrameImpl::OnReplace(const base::string16& text) { 2005 void RenderFrameImpl::OnReplace(const base::string16& text) {
2004 if (!frame_->HasSelection()) 2006 if (!frame_->HasSelection())
2005 frame_->SelectWordAroundCaret(); 2007 frame_->SelectWordAroundCaret();
2006 2008
2007 frame_->ReplaceSelection(WebString::FromUTF16(text)); 2009 frame_->ReplaceSelection(WebString::FromUTF16(text));
2008 SyncSelectionIfRequired(); 2010 // Handle this selection change as user initiated since typically triggered
2011 // from context menu.
2012 SyncSelectionIfRequired(true);
2009 } 2013 }
2010 2014
2011 void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) { 2015 void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) {
2012 if (!frame_->HasSelection()) 2016 if (!frame_->HasSelection())
2013 return; 2017 return;
2014 2018
2015 frame_->ReplaceMisspelledRange(WebString::FromUTF16(text)); 2019 frame_->ReplaceMisspelledRange(WebString::FromUTF16(text));
2016 } 2020 }
2017 2021
2018 void RenderFrameImpl::OnCopyImageAt(int x, int y) { 2022 void RenderFrameImpl::OnCopyImageAt(int x, int y) {
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 void RenderFrameImpl::AttachGuest(int element_instance_id) { 2704 void RenderFrameImpl::AttachGuest(int element_instance_id) {
2701 BrowserPluginManager::Get()->Attach(element_instance_id); 2705 BrowserPluginManager::Get()->Attach(element_instance_id);
2702 } 2706 }
2703 2707
2704 void RenderFrameImpl::DetachGuest(int element_instance_id) { 2708 void RenderFrameImpl::DetachGuest(int element_instance_id) {
2705 BrowserPluginManager::Get()->Detach(element_instance_id); 2709 BrowserPluginManager::Get()->Detach(element_instance_id);
2706 } 2710 }
2707 2711
2708 void RenderFrameImpl::SetSelectedText(const base::string16& selection_text, 2712 void RenderFrameImpl::SetSelectedText(const base::string16& selection_text,
2709 size_t offset, 2713 size_t offset,
2710 const gfx::Range& range) { 2714 const gfx::Range& range,
2715 bool user_initiated) {
2711 Send(new FrameHostMsg_SelectionChanged(routing_id_, selection_text, 2716 Send(new FrameHostMsg_SelectionChanged(routing_id_, selection_text,
2712 static_cast<uint32_t>(offset), range)); 2717 static_cast<uint32_t>(offset), range,
2718 user_initiated));
2713 } 2719 }
2714 2720
2715 void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable( 2721 void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
2716 v8::Isolate* isolate, 2722 v8::Isolate* isolate,
2717 v8::Local<v8::Context> context) { 2723 v8::Local<v8::Context> context) {
2718 gin::ModuleRegistry* registry = gin::ModuleRegistry::From(context); 2724 gin::ModuleRegistry* registry = gin::ModuleRegistry::From(context);
2719 if (registry->available_modules().count(mojo::edk::js::Core::kModuleName)) 2725 if (registry->available_modules().count(mojo::edk::js::Core::kModuleName))
2720 return; 2726 return;
2721 2727
2722 v8::HandleScope handle_scope(isolate); 2728 v8::HandleScope handle_scope(isolate);
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after
4080 return false; 4086 return false;
4081 } 4087 }
4082 return true; 4088 return true;
4083 } 4089 }
4084 4090
4085 void RenderFrameImpl::AbortClientNavigation() { 4091 void RenderFrameImpl::AbortClientNavigation() {
4086 Send(new FrameHostMsg_AbortNavigation(routing_id_)); 4092 Send(new FrameHostMsg_AbortNavigation(routing_id_));
4087 } 4093 }
4088 4094
4089 void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) { 4095 void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) {
4090 if (!GetRenderWidget()->input_handler().handling_input_event() && 4096 bool user_initiated =
4091 !handling_select_range_) 4097 GetRenderWidget()->input_handler().handling_input_event() ||
4092 return; 4098 handling_select_range_;
4099
4100 if (!user_initiated) {
4101 // Do not update text input state unnecessarily when text selection remains
4102 // empty.
4103 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
4104 return;
4105
4106 // Ignore selection change of text replacement triggered by IME composition.
4107 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
4108 return;
4109 }
4093 4110
4094 if (is_empty_selection) 4111 if (is_empty_selection)
4095 selection_text_.clear(); 4112 selection_text_.clear();
4096 4113
4097 // UpdateTextInputState should be called before SyncSelectionIfRequired. 4114 // UpdateTextInputState should be called before SyncSelectionIfRequired.
4098 // UpdateTextInputState may send TextInputStateChanged to notify the focus 4115 // UpdateTextInputState may send TextInputStateChanged to notify the focus
4099 // was changed, and SyncSelectionIfRequired may send SelectionChanged 4116 // was changed, and SyncSelectionIfRequired may send SelectionChanged
4100 // to notify the selection was changed. Focus change should be notified 4117 // to notify the selection was changed. Focus change should be notified
4101 // before selection change. 4118 // before selection change.
4102 GetRenderWidget()->UpdateTextInputState(); 4119 GetRenderWidget()->UpdateTextInputState();
4103 SyncSelectionIfRequired(); 4120 SyncSelectionIfRequired(user_initiated);
4104 } 4121 }
4105 4122
4106 bool RenderFrameImpl::HandleCurrentKeyboardEvent() { 4123 bool RenderFrameImpl::HandleCurrentKeyboardEvent() {
4107 bool did_execute_command = false; 4124 bool did_execute_command = false;
4108 for (auto command : GetRenderWidget()->edit_commands()) { 4125 for (auto command : GetRenderWidget()->edit_commands()) {
4109 // In gtk and cocoa, it's possible to bind multiple edit commands to one 4126 // In gtk and cocoa, it's possible to bind multiple edit commands to one
4110 // key (but it's the exception). Once one edit command is not executed, it 4127 // key (but it's the exception). Once one edit command is not executed, it
4111 // seems safest to not execute the rest. 4128 // seems safest to not execute the rest.
4112 if (!frame_->ExecuteCommand(blink::WebString::FromUTF8(command.name), 4129 if (!frame_->ExecuteCommand(blink::WebString::FromUTF8(command.name),
4113 blink::WebString::FromUTF8(command.value))) 4130 blink::WebString::FromUTF8(command.value)))
(...skipping 2089 matching lines...) Expand 10 before | Expand all | Expand 10 after
6203 } 6220 }
6204 } 6221 }
6205 6222
6206 void RenderFrameImpl::UpdateEncoding(WebFrame* frame, 6223 void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
6207 const std::string& encoding_name) { 6224 const std::string& encoding_name) {
6208 // Only update main frame's encoding_name. 6225 // Only update main frame's encoding_name.
6209 if (!frame->Parent()) 6226 if (!frame->Parent())
6210 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name)); 6227 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name));
6211 } 6228 }
6212 6229
6213 void RenderFrameImpl::SyncSelectionIfRequired() { 6230 void RenderFrameImpl::SyncSelectionIfRequired(bool user_initiated) {
6214 base::string16 text; 6231 base::string16 text;
6215 size_t offset; 6232 size_t offset = 0;
6216 gfx::Range range; 6233 gfx::Range range = gfx::Range::InvalidRange();
6217 #if BUILDFLAG(ENABLE_PLUGINS) 6234 #if BUILDFLAG(ENABLE_PLUGINS)
6218 if (focused_pepper_plugin_) { 6235 if (focused_pepper_plugin_) {
6219 focused_pepper_plugin_->GetSurroundingText(&text, &range); 6236 focused_pepper_plugin_->GetSurroundingText(&text, &range);
6220 offset = 0; // Pepper API does not support offset reporting. 6237 offset = 0; // Pepper API does not support offset reporting.
6221 // TODO(kinaba): cut as needed. 6238 // TODO(kinaba): cut as needed.
6222 } else 6239 } else
6223 #endif 6240 #endif
6224 { 6241 {
6225 WebRange selection = 6242 WebRange selection =
6226 GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); 6243 GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
6227 if (selection.IsNull()) 6244
6245 // When clearing text selection from JavaScript the selection range
6246 // might be null but the selected text still have to be updated.
6247 // Do not cancel sync selection if the clear was not user initiated.
6248 if (!selection.IsNull()) {
6249 range = gfx::Range(selection.StartOffset(), selection.EndOffset());
6250
6251 if (frame_->GetInputMethodController()->TextInputType() !=
6252 blink::kWebTextInputTypeNone) {
6253 // If current focused element is editable, we will send 100 more chars
6254 // before and after selection. It is for input method surrounding text
6255 // feature.
6256 if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
6257 offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
6258 else
6259 offset = 0;
6260 size_t length =
6261 selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
6262 text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
6263 } else {
6264 offset = selection.StartOffset();
6265 text = frame_->SelectionAsText().Utf16();
6266 // http://crbug.com/101435
6267 // In some case, frame->selectionAsText() returned text's length is not
6268 // equal to the length returned from
6269 // GetWebWidget()->caretOrSelectionRange().
6270 // So we have to set the range according to text.length().
6271 range.set_end(range.start() + text.length());
6272 }
6273 } else if (user_initiated) {
6228 return; 6274 return;
6229
6230 range = gfx::Range(selection.StartOffset(), selection.EndOffset());
6231
6232 if (frame_->GetInputMethodController()->TextInputType() !=
6233 blink::kWebTextInputTypeNone) {
6234 // If current focused element is editable, we will send 100 more chars
6235 // before and after selection. It is for input method surrounding text
6236 // feature.
6237 if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
6238 offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
6239 else
6240 offset = 0;
6241 size_t length =
6242 selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
6243 text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
6244 } else {
6245 offset = selection.StartOffset();
6246 text = frame_->SelectionAsText().Utf16();
6247 // http://crbug.com/101435
6248 // In some case, frame->selectionAsText() returned text's length is not
6249 // equal to the length returned from
6250 // GetWebWidget()->caretOrSelectionRange().
6251 // So we have to set the range according to text.length().
6252 range.set_end(range.start() + text.length());
6253 } 6275 }
6254 } 6276 }
6255 6277
6256 // TODO(dglazkov): Investigate if and why this would be happening, 6278 // TODO(dglazkov): Investigate if and why this would be happening,
6257 // and resolve this. We shouldn't be carrying selection text here. 6279 // and resolve this. We shouldn't be carrying selection text here.
6258 // http://crbug.com/632920. 6280 // http://crbug.com/632920.
6259 // Sometimes we get repeated didChangeSelection calls from webkit when 6281 // Sometimes we get repeated didChangeSelection calls from webkit when
6260 // the selection hasn't actually changed. We don't want to report these 6282 // the selection hasn't actually changed. We don't want to report these
6261 // because it will cause us to continually claim the X clipboard. 6283 // because it will cause us to continually claim the X clipboard.
6262 if (selection_text_offset_ != offset || 6284 if (selection_text_offset_ != offset ||
6263 selection_range_ != range || 6285 selection_range_ != range ||
6264 selection_text_ != text) { 6286 selection_text_ != text) {
6265 selection_text_ = text; 6287 selection_text_ = text;
6266 selection_text_offset_ = offset; 6288 selection_text_offset_ = offset;
6267 selection_range_ = range; 6289 selection_range_ = range;
6268 SetSelectedText(text, offset, range); 6290 SetSelectedText(text, offset, range, user_initiated);
6269 } 6291 }
6270 GetRenderWidget()->UpdateSelectionBounds(); 6292 GetRenderWidget()->UpdateSelectionBounds();
6271 } 6293 }
6272 6294
6273 void RenderFrameImpl::InitializeUserMediaClient() { 6295 void RenderFrameImpl::InitializeUserMediaClient() {
6274 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 6296 RenderThreadImpl* render_thread = RenderThreadImpl::current();
6275 if (!render_thread) // Will be NULL during unit tests. 6297 if (!render_thread) // Will be NULL during unit tests.
6276 return; 6298 return;
6277 6299
6278 #if BUILDFLAG(ENABLE_WEBRTC) 6300 #if BUILDFLAG(ENABLE_WEBRTC)
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
6893 replaces_current_history_item(info.replaces_current_history_item), 6915 replaces_current_history_item(info.replaces_current_history_item),
6894 history_navigation_in_new_child_frame( 6916 history_navigation_in_new_child_frame(
6895 info.is_history_navigation_in_new_child_frame), 6917 info.is_history_navigation_in_new_child_frame),
6896 client_redirect(info.is_client_redirect), 6918 client_redirect(info.is_client_redirect),
6897 triggering_event_info(info.triggering_event_info), 6919 triggering_event_info(info.triggering_event_info),
6898 cache_disabled(info.is_cache_disabled), 6920 cache_disabled(info.is_cache_disabled),
6899 form(info.form), 6921 form(info.form),
6900 source_location(info.source_location) {} 6922 source_location(info.source_location) {}
6901 6923
6902 } // namespace content 6924 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698