| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/ui/browser.h" | 9 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 10 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 void VerifyChange() { | 229 void VerifyChange() { |
| 230 if (expected_view_ == tester()->GetUpdatedView()) | 230 if (expected_view_ == tester()->GetUpdatedView()) |
| 231 OnSuccess(); | 231 OnSuccess(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 const content::RenderWidgetHostView* const expected_view_; | 234 const content::RenderWidgetHostView* const expected_view_; |
| 235 | 235 |
| 236 DISALLOW_COPY_AND_ASSIGN(ViewCompositionRangeChangedObserver); | 236 DISALLOW_COPY_AND_ASSIGN(ViewCompositionRangeChangedObserver); |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 // This class observes the |expected_view| for a change in the text selection | 239 // This class observes the |expected_view| for a change in the text selection. |
| 240 // that has a selection length of |expected_length|. | |
| 241 class ViewTextSelectionObserver : public TextInputManagerObserverBase { | 240 class ViewTextSelectionObserver : public TextInputManagerObserverBase { |
| 242 public: | 241 public: |
| 243 ViewTextSelectionObserver(content::WebContents* web_contents, | 242 ViewTextSelectionObserver(content::WebContents* web_contents, |
| 244 content::RenderWidgetHostView* expected_view, | 243 content::RenderWidgetHostView* expected_view, |
| 245 size_t expected_selection_length) | 244 size_t expected_length) |
| 246 : TextInputManagerObserverBase(web_contents), | 245 : TextInputManagerObserverBase(web_contents), |
| 247 expected_view_(expected_view), | 246 expected_view_(expected_view), |
| 248 expected_selection_length_(expected_selection_length) { | 247 expected_length_(expected_length) { |
| 249 tester()->SetOnTextSelectionChangedCallback(base::Bind( | 248 tester()->SetOnTextSelectionChangedCallback(base::Bind( |
| 250 &ViewTextSelectionObserver::VerifyChange, base::Unretained(this))); | 249 &ViewTextSelectionObserver::VerifyChange, base::Unretained(this))); |
| 251 } | 250 } |
| 252 | 251 |
| 253 private: | 252 private: |
| 254 void VerifyChange() { | 253 void VerifyChange() { |
| 255 if (expected_view_ == tester()->GetUpdatedView()) { | 254 if (expected_view_ == tester()->GetUpdatedView()) { |
| 256 size_t selection_length; | 255 size_t length; |
| 257 if (tester()->GetCurrentTextSelectionLength(&selection_length) && | 256 EXPECT_TRUE(tester()->GetCurrentTextSelectionLength(&length)); |
| 258 expected_selection_length_ == selection_length) | 257 if (length == expected_length_) |
| 259 OnSuccess(); | 258 OnSuccess(); |
| 260 } | 259 } |
| 261 } | 260 } |
| 262 | 261 |
| 263 const content::RenderWidgetHostView* const expected_view_; | 262 const content::RenderWidgetHostView* const expected_view_; |
| 264 const size_t expected_selection_length_; | 263 const size_t expected_length_; |
| 265 | 264 |
| 266 DISALLOW_COPY_AND_ASSIGN(ViewTextSelectionObserver); | 265 DISALLOW_COPY_AND_ASSIGN(ViewTextSelectionObserver); |
| 267 }; | 266 }; |
| 268 | 267 |
| 269 // This class monitors all the changes in TextInputState and keeps a record of | 268 // This class monitors all the changes in TextInputState and keeps a record of |
| 270 // the active views. There is no waiting and the recording process is | 269 // the active views. There is no waiting and the recording process is |
| 271 // continuous. | 270 // continuous. |
| 272 class RecordActiveViewsObserver { | 271 class RecordActiveViewsObserver { |
| 273 public: | 272 public: |
| 274 explicit RecordActiveViewsObserver(content::WebContents* web_contents) | 273 explicit RecordActiveViewsObserver(content::WebContents* web_contents) |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 {ui::CompositionUnderline()}, gfx::Range::InvalidRange(), 0, 0); | 639 {ui::CompositionUnderline()}, gfx::Range::InvalidRange(), 0, 0); |
| 641 range_observer.Wait(); | 640 range_observer.Wait(); |
| 642 }; | 641 }; |
| 643 | 642 |
| 644 for (auto* view : views) | 643 for (auto* view : views) |
| 645 send_tab_set_composition_wait_for_bounds_change(view); | 644 send_tab_set_composition_wait_for_bounds_change(view); |
| 646 } | 645 } |
| 647 | 646 |
| 648 // This test creates a page with multiple child frames and adds an <input> to | 647 // This test creates a page with multiple child frames and adds an <input> to |
| 649 // each frame. Then, sequentially, each <input> is focused by sending a tab key. | 648 // each frame. Then, sequentially, each <input> is focused by sending a tab key. |
| 650 // After focusing each input, the whole text is automatically selected and a | 649 // After focusing each input, a sequence of key presses (character 'E') are sent |
| 651 // ViewHostMsg_SelectionChanged IPC sent back to the browser. This test verifies | 650 // to the focused widget and then the whole text is selected using Ctrl+A. The |
| 652 // that the browser tracks the text selection from all frames. | 651 // test then verifies that the selection length equals the length of the |
| 652 // sequence of 'E's. |
| 653 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | 653 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, |
| 654 TrackTextSelectionForAllFrames) { | 654 TrackTextSelectionForAllFrames) { |
| 655 // TODO(ekaramad): Since IME related methods in WebFrameWidgetImpl are not | 655 CreateIframePage("a(b,c(a,b),d)"); |
| 656 // implemented yet, this test does not work on child frames. Add child frames | 656 std::vector<content::RenderFrameHost*> frames{ |
| 657 // to this test when IME methods in WebFramgeWidgetImpl are implemented | 657 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), |
| 658 // (https://crbug.com/626746). | 658 GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), |
| 659 CreateIframePage("a()"); | 659 GetFrame(IndexVector{1, 1}), GetFrame(IndexVector{2})}; |
| 660 std::vector<content::RenderFrameHost*> frames{GetFrame(IndexVector{})}; | 660 std::vector<std::string> values{"main", "b", "c", "ca", "cb", "d"}; |
| 661 std::vector<content::RenderWidgetHostView*> views; | 661 std::vector<content::RenderWidgetHostView*> views; |
| 662 for (auto frame : frames) | 662 for (auto* frame : frames) |
| 663 views.push_back(frame->GetView()); | 663 views.push_back(frame->GetView()); |
| 664 std::vector<std::string> input_text{"abc"}; | |
| 665 for (size_t i = 0; i < frames.size(); ++i) | 664 for (size_t i = 0; i < frames.size(); ++i) |
| 666 AddInputFieldToFrame(frames[i], "text", input_text[i], false); | 665 AddInputFieldToFrame(frames[i], "text", values[i], true); |
| 667 | 666 |
| 668 content::WebContents* web_contents = active_contents(); | 667 content::WebContents* web_contents = active_contents(); |
| 669 | 668 |
| 670 auto send_tab_and_wait_for_selection_change = [&web_contents]( | 669 auto send_tab_and_wait_for_value = [&web_contents](const std::string& value) { |
| 671 content::RenderFrameHost* frame, size_t expected_length) { | 670 TextInputManagerValueObserver observer(web_contents, value); |
| 672 ViewTextSelectionObserver text_selection_observer( | |
| 673 web_contents, frame->GetView(), expected_length); | |
| 674 SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, | 671 SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, |
| 675 ui::VKEY_TAB, false, false, false, false); | 672 ui::VKEY_TAB, false, false, false, false); |
| 676 text_selection_observer.Wait(); | 673 observer.Wait(); |
| 677 }; | 674 }; |
| 678 | 675 |
| 679 for (size_t i = 0; i < frames.size(); ++i) | 676 auto send_keys_select_all_wait_for_selection_change = [&web_contents]( |
| 680 send_tab_and_wait_for_selection_change(frames[i], input_text[i].size()); | 677 content::RenderWidgetHostView* view, size_t count) { |
| 678 ViewTextSelectionObserver observer(web_contents, view, count); |
| 679 for (size_t i = 0; i < count; ++i) { |
| 680 SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('E'), |
| 681 ui::DomCode::US_E, ui::VKEY_E, false, false, false, |
| 682 false); |
| 683 } |
| 684 // Send Ctrl+A to select the whole text. |
| 685 SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('a'), |
| 686 ui::DomCode::US_A, ui::VKEY_A, true, false, false, false); |
| 687 observer.Wait(); |
| 688 }; |
| 689 |
| 690 size_t count = 2; |
| 691 for (size_t i = 0; i < views.size(); ++i) { |
| 692 // First focus the <input>. |
| 693 send_tab_and_wait_for_value(values[i]); |
| 694 |
| 695 // Send a sequence of |count| 'E' keys and wait until the view receives a |
| 696 // selection change update for a text of the corresponding size, |count|. |
| 697 send_keys_select_all_wait_for_selection_change(views[i], count++); |
| 698 } |
| 681 } | 699 } |
| 682 | 700 |
| 683 // The following test verifies that when the active widget changes value, it is | 701 // The following test verifies that when the active widget changes value, it is |
| 684 // always from nullptr to non-null or vice versa. | 702 // always from nullptr to non-null or vice versa. |
| 685 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, | 703 IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, |
| 686 ResetTextInputStateOnActiveWidgetChange) { | 704 ResetTextInputStateOnActiveWidgetChange) { |
| 687 CreateIframePage("a(b,c(a,b),d)"); | 705 CreateIframePage("a(b,c(a,b),d)"); |
| 688 std::vector<content::RenderFrameHost*> frames{ | 706 std::vector<content::RenderFrameHost*> frames{ |
| 689 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), | 707 GetFrame(IndexVector{}), GetFrame(IndexVector{0}), |
| 690 GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), | 708 GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 | 859 |
| 842 // Set |TextInputState.show_ime_if_needed|. Expect IME. | 860 // Set |TextInputState.show_ime_if_needed|. Expect IME. |
| 843 sender.SetShowImeIfNeeded(true); | 861 sender.SetShowImeIfNeeded(true); |
| 844 EXPECT_TRUE(send_and_check_show_ime()); | 862 EXPECT_TRUE(send_and_check_show_ime()); |
| 845 | 863 |
| 846 // Set |TextInputState.type| to ui::TEXT_INPUT_TYPE_NONE. Expect no IME. | 864 // Set |TextInputState.type| to ui::TEXT_INPUT_TYPE_NONE. Expect no IME. |
| 847 sender.SetType(ui::TEXT_INPUT_TYPE_NONE); | 865 sender.SetType(ui::TEXT_INPUT_TYPE_NONE); |
| 848 EXPECT_FALSE(send_and_check_show_ime()); | 866 EXPECT_FALSE(send_and_check_show_ime()); |
| 849 } | 867 } |
| 850 #endif // USE_AURA | 868 #endif // USE_AURA |
| OLD | NEW |