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

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 2903833002: Reland: Update TextSelection for non-user initiated events
Patch Set: Add test for JS cursor movement 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
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_widget.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 #if defined(OS_MACOSX) || defined(USE_AURA) 1408 #if defined(OS_MACOSX) || defined(USE_AURA)
1409 GetRenderWidget()->UpdateCompositionInfo( 1409 GetRenderWidget()->UpdateCompositionInfo(
1410 false /* not an immediate request */); 1410 false /* not an immediate request */);
1411 #endif 1411 #endif
1412 } 1412 }
1413 1413
1414 void RenderFrameImpl::PepperSelectionChanged( 1414 void RenderFrameImpl::PepperSelectionChanged(
1415 PepperPluginInstanceImpl* instance) { 1415 PepperPluginInstanceImpl* instance) {
1416 if (instance != focused_pepper_plugin_) 1416 if (instance != focused_pepper_plugin_)
1417 return; 1417 return;
1418 SyncSelectionIfRequired(); 1418 // Keep the original behavior for pepper plugins and handle all selection
1419 // change as user initiated.
1420 SyncSelectionIfRequired(true);
1419 } 1421 }
1420 1422
1421 RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer( 1423 RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
1422 PepperPluginInstanceImpl* plugin) { 1424 PepperPluginInstanceImpl* plugin) {
1423 GURL active_url; 1425 GURL active_url;
1424 if (render_view()->webview()) 1426 if (render_view()->webview())
1425 active_url = render_view()->GetURLForGraphicsContext3D(); 1427 active_url = render_view()->GetURLForGraphicsContext3D();
1426 1428
1427 mojom::WidgetPtr widget_channel; 1429 mojom::WidgetPtr widget_channel;
1428 mojom::WidgetRequest widget_channel_request = 1430 mojom::WidgetRequest widget_channel_request =
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
2014 base::AutoReset<bool> handling_select_range(&handling_select_range_, true); 2016 base::AutoReset<bool> handling_select_range(&handling_select_range_, true);
2015 frame_->MoveRangeSelectionExtent( 2017 frame_->MoveRangeSelectionExtent(
2016 render_view_->ConvertWindowPointToViewport(point)); 2018 render_view_->ConvertWindowPointToViewport(point));
2017 } 2019 }
2018 2020
2019 void RenderFrameImpl::OnReplace(const base::string16& text) { 2021 void RenderFrameImpl::OnReplace(const base::string16& text) {
2020 if (!frame_->HasSelection()) 2022 if (!frame_->HasSelection())
2021 frame_->SelectWordAroundCaret(); 2023 frame_->SelectWordAroundCaret();
2022 2024
2023 frame_->ReplaceSelection(WebString::FromUTF16(text)); 2025 frame_->ReplaceSelection(WebString::FromUTF16(text));
2024 SyncSelectionIfRequired(); 2026 // Handle this selection change as user initiated since typically triggered
2027 // from context menu.
2028 SyncSelectionIfRequired(true);
2025 } 2029 }
2026 2030
2027 void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) { 2031 void RenderFrameImpl::OnReplaceMisspelling(const base::string16& text) {
2028 if (!frame_->HasSelection()) 2032 if (!frame_->HasSelection())
2029 return; 2033 return;
2030 2034
2031 frame_->ReplaceMisspelledRange(WebString::FromUTF16(text)); 2035 frame_->ReplaceMisspelledRange(WebString::FromUTF16(text));
2032 } 2036 }
2033 2037
2034 void RenderFrameImpl::OnCopyImageAt(int x, int y) { 2038 void RenderFrameImpl::OnCopyImageAt(int x, int y) {
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 void RenderFrameImpl::AttachGuest(int element_instance_id) { 2720 void RenderFrameImpl::AttachGuest(int element_instance_id) {
2717 BrowserPluginManager::Get()->Attach(element_instance_id); 2721 BrowserPluginManager::Get()->Attach(element_instance_id);
2718 } 2722 }
2719 2723
2720 void RenderFrameImpl::DetachGuest(int element_instance_id) { 2724 void RenderFrameImpl::DetachGuest(int element_instance_id) {
2721 BrowserPluginManager::Get()->Detach(element_instance_id); 2725 BrowserPluginManager::Get()->Detach(element_instance_id);
2722 } 2726 }
2723 2727
2724 void RenderFrameImpl::SetSelectedText(const base::string16& selection_text, 2728 void RenderFrameImpl::SetSelectedText(const base::string16& selection_text,
2725 size_t offset, 2729 size_t offset,
2726 const gfx::Range& range) { 2730 const gfx::Range& range,
2731 bool user_initiated) {
2727 Send(new FrameHostMsg_SelectionChanged(routing_id_, selection_text, 2732 Send(new FrameHostMsg_SelectionChanged(routing_id_, selection_text,
2728 static_cast<uint32_t>(offset), range)); 2733 static_cast<uint32_t>(offset), range,
2734 user_initiated));
2729 } 2735 }
2730 2736
2731 void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable( 2737 void RenderFrameImpl::EnsureMojoBuiltinsAreAvailable(
2732 v8::Isolate* isolate, 2738 v8::Isolate* isolate,
2733 v8::Local<v8::Context> context) { 2739 v8::Local<v8::Context> context) {
2734 gin::ModuleRegistry* registry = gin::ModuleRegistry::From(context); 2740 gin::ModuleRegistry* registry = gin::ModuleRegistry::From(context);
2735 if (registry->available_modules().count(mojo::edk::js::Core::kModuleName)) 2741 if (registry->available_modules().count(mojo::edk::js::Core::kModuleName))
2736 return; 2742 return;
2737 2743
2738 v8::HandleScope handle_scope(isolate); 2744 v8::HandleScope handle_scope(isolate);
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after
4097 return false; 4103 return false;
4098 } 4104 }
4099 return true; 4105 return true;
4100 } 4106 }
4101 4107
4102 void RenderFrameImpl::AbortClientNavigation() { 4108 void RenderFrameImpl::AbortClientNavigation() {
4103 Send(new FrameHostMsg_AbortNavigation(routing_id_)); 4109 Send(new FrameHostMsg_AbortNavigation(routing_id_));
4104 } 4110 }
4105 4111
4106 void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) { 4112 void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) {
4107 if (!GetRenderWidget()->input_handler().handling_input_event() && 4113 bool user_initiated =
4108 !handling_select_range_) 4114 GetRenderWidget()->input_handler().handling_input_event() ||
4109 return; 4115 handling_select_range_;
4116
4117 if (!user_initiated) {
4118 // Do not update text input state unnecessarily when text selection remains
4119 // empty.
4120 if (is_empty_selection && selection_text_.empty())
4121 return;
4122
4123 // Ignore selection change of text replacement triggered by IME composition.
4124 if (GetRenderWidget()->input_handler().ime_composition_replacement())
4125 return;
4126 }
4110 4127
4111 if (is_empty_selection) 4128 if (is_empty_selection)
4112 selection_text_.clear(); 4129 selection_text_.clear();
4113 4130
4114 // UpdateTextInputState should be called before SyncSelectionIfRequired. 4131 // UpdateTextInputState should be called before SyncSelectionIfRequired.
4115 // UpdateTextInputState may send TextInputStateChanged to notify the focus 4132 // UpdateTextInputState may send TextInputStateChanged to notify the focus
4116 // was changed, and SyncSelectionIfRequired may send SelectionChanged 4133 // was changed, and SyncSelectionIfRequired may send SelectionChanged
4117 // to notify the selection was changed. Focus change should be notified 4134 // to notify the selection was changed. Focus change should be notified
4118 // before selection change. 4135 // before selection change.
4119 GetRenderWidget()->UpdateTextInputState(); 4136 GetRenderWidget()->UpdateTextInputState();
4120 SyncSelectionIfRequired(); 4137 SyncSelectionIfRequired(user_initiated);
4121 } 4138 }
4122 4139
4123 bool RenderFrameImpl::HandleCurrentKeyboardEvent() { 4140 bool RenderFrameImpl::HandleCurrentKeyboardEvent() {
4124 bool did_execute_command = false; 4141 bool did_execute_command = false;
4125 for (auto command : GetRenderWidget()->edit_commands()) { 4142 for (auto command : GetRenderWidget()->edit_commands()) {
4126 // In gtk and cocoa, it's possible to bind multiple edit commands to one 4143 // In gtk and cocoa, it's possible to bind multiple edit commands to one
4127 // key (but it's the exception). Once one edit command is not executed, it 4144 // key (but it's the exception). Once one edit command is not executed, it
4128 // seems safest to not execute the rest. 4145 // seems safest to not execute the rest.
4129 if (!frame_->ExecuteCommand(blink::WebString::FromUTF8(command.name), 4146 if (!frame_->ExecuteCommand(blink::WebString::FromUTF8(command.name),
4130 blink::WebString::FromUTF8(command.value))) 4147 blink::WebString::FromUTF8(command.value)))
(...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after
6195 } 6212 }
6196 } 6213 }
6197 6214
6198 void RenderFrameImpl::UpdateEncoding(WebFrame* frame, 6215 void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
6199 const std::string& encoding_name) { 6216 const std::string& encoding_name) {
6200 // Only update main frame's encoding_name. 6217 // Only update main frame's encoding_name.
6201 if (!frame->Parent()) 6218 if (!frame->Parent())
6202 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name)); 6219 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name));
6203 } 6220 }
6204 6221
6205 void RenderFrameImpl::SyncSelectionIfRequired() { 6222 void RenderFrameImpl::SyncSelectionIfRequired(bool user_initiated) {
6206 base::string16 text; 6223 base::string16 text;
6207 size_t offset; 6224 size_t offset = 0;
6208 gfx::Range range; 6225 gfx::Range range = gfx::Range::InvalidRange();
6209 #if BUILDFLAG(ENABLE_PLUGINS) 6226 #if BUILDFLAG(ENABLE_PLUGINS)
6210 if (focused_pepper_plugin_) { 6227 if (focused_pepper_plugin_) {
6211 focused_pepper_plugin_->GetSurroundingText(&text, &range); 6228 focused_pepper_plugin_->GetSurroundingText(&text, &range);
6212 offset = 0; // Pepper API does not support offset reporting. 6229 offset = 0; // Pepper API does not support offset reporting.
6213 // TODO(kinaba): cut as needed. 6230 // TODO(kinaba): cut as needed.
6214 } else 6231 } else
6215 #endif 6232 #endif
6216 { 6233 {
6217 WebRange selection = 6234 WebRange selection =
6218 GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange(); 6235 GetRenderWidget()->GetWebWidget()->CaretOrSelectionRange();
6219 if (selection.IsNull()) 6236
6237 // When clearing text selection from JavaScript the selection range
6238 // might be null but the selected text still have to be updated.
6239 // Do not cancel sync selection if the clear was not user initiated.
6240 if (!selection.IsNull()) {
6241 range = gfx::Range(selection.StartOffset(), selection.EndOffset());
6242
6243 if (frame_->GetInputMethodController()->TextInputType() !=
6244 blink::kWebTextInputTypeNone) {
6245 // If current focused element is editable, we will send 100 more chars
6246 // before and after selection. It is for input method surrounding text
6247 // feature.
6248 if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
6249 offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
6250 else
6251 offset = 0;
6252 size_t length =
6253 selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
6254 text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
6255 } else {
6256 offset = selection.StartOffset();
6257 text = frame_->SelectionAsText().Utf16();
6258 // http://crbug.com/101435
6259 // In some case, frame->selectionAsText() returned text's length is not
6260 // equal to the length returned from
6261 // GetWebWidget()->caretOrSelectionRange().
6262 // So we have to set the range according to text.length().
6263 range.set_end(range.start() + text.length());
6264 }
6265 } else if (user_initiated) {
6220 return; 6266 return;
6221
6222 range = gfx::Range(selection.StartOffset(), selection.EndOffset());
6223
6224 if (frame_->GetInputMethodController()->TextInputType() !=
6225 blink::kWebTextInputTypeNone) {
6226 // If current focused element is editable, we will send 100 more chars
6227 // before and after selection. It is for input method surrounding text
6228 // feature.
6229 if (selection.StartOffset() > kExtraCharsBeforeAndAfterSelection)
6230 offset = selection.StartOffset() - kExtraCharsBeforeAndAfterSelection;
6231 else
6232 offset = 0;
6233 size_t length =
6234 selection.EndOffset() - offset + kExtraCharsBeforeAndAfterSelection;
6235 text = frame_->RangeAsText(WebRange(offset, length)).Utf16();
6236 } else {
6237 offset = selection.StartOffset();
6238 text = frame_->SelectionAsText().Utf16();
6239 // http://crbug.com/101435
6240 // In some case, frame->selectionAsText() returned text's length is not
6241 // equal to the length returned from
6242 // GetWebWidget()->caretOrSelectionRange().
6243 // So we have to set the range according to text.length().
6244 range.set_end(range.start() + text.length());
6245 } 6267 }
6246 } 6268 }
6247 6269
6248 // TODO(dglazkov): Investigate if and why this would be happening, 6270 // TODO(dglazkov): Investigate if and why this would be happening,
6249 // and resolve this. We shouldn't be carrying selection text here. 6271 // and resolve this. We shouldn't be carrying selection text here.
6250 // http://crbug.com/632920. 6272 // http://crbug.com/632920.
6251 // Sometimes we get repeated didChangeSelection calls from webkit when 6273 // Sometimes we get repeated didChangeSelection calls from webkit when
6252 // the selection hasn't actually changed. We don't want to report these 6274 // the selection hasn't actually changed. We don't want to report these
6253 // because it will cause us to continually claim the X clipboard. 6275 // because it will cause us to continually claim the X clipboard.
6254 if (selection_text_offset_ != offset || 6276 if (selection_text_offset_ != offset ||
6255 selection_range_ != range || 6277 selection_range_ != range ||
6256 selection_text_ != text) { 6278 selection_text_ != text) {
6257 selection_text_ = text; 6279 selection_text_ = text;
6258 selection_text_offset_ = offset; 6280 selection_text_offset_ = offset;
6259 selection_range_ = range; 6281 selection_range_ = range;
6260 SetSelectedText(text, offset, range); 6282 SetSelectedText(text, offset, range, user_initiated);
6261 } 6283 }
6262 GetRenderWidget()->UpdateSelectionBounds(); 6284 GetRenderWidget()->UpdateSelectionBounds();
6263 } 6285 }
6264 6286
6265 void RenderFrameImpl::InitializeUserMediaClient() { 6287 void RenderFrameImpl::InitializeUserMediaClient() {
6266 RenderThreadImpl* render_thread = RenderThreadImpl::current(); 6288 RenderThreadImpl* render_thread = RenderThreadImpl::current();
6267 if (!render_thread) // Will be NULL during unit tests. 6289 if (!render_thread) // Will be NULL during unit tests.
6268 return; 6290 return;
6269 6291
6270 #if BUILDFLAG(ENABLE_WEBRTC) 6292 #if BUILDFLAG(ENABLE_WEBRTC)
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
6903 replaces_current_history_item(info.replaces_current_history_item), 6925 replaces_current_history_item(info.replaces_current_history_item),
6904 history_navigation_in_new_child_frame( 6926 history_navigation_in_new_child_frame(
6905 info.is_history_navigation_in_new_child_frame), 6927 info.is_history_navigation_in_new_child_frame),
6906 client_redirect(info.is_client_redirect), 6928 client_redirect(info.is_client_redirect),
6907 triggering_event_info(info.triggering_event_info), 6929 triggering_event_info(info.triggering_event_info),
6908 cache_disabled(info.is_cache_disabled), 6930 cache_disabled(info.is_cache_disabled),
6909 form(info.form), 6931 form(info.form),
6910 source_location(info.source_location) {} 6932 source_location(info.source_location) {}
6911 6933
6912 } // namespace content 6934 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_widget.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698