| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_native_widget.h" | 5 #import "ui/views/cocoa/bridged_native_widget.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 void InstallTextField(const std::string& text, | 200 void InstallTextField(const std::string& text, |
| 201 ui::TextInputType text_input_type); | 201 ui::TextInputType text_input_type); |
| 202 | 202 |
| 203 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view | 203 // Install a textfield with input type ui::TEXT_INPUT_TYPE_TEXT in the view |
| 204 // hierarchy and make it the text input client. | 204 // hierarchy and make it the text input client. |
| 205 void InstallTextField(const std::string& text); | 205 void InstallTextField(const std::string& text); |
| 206 | 206 |
| 207 // Returns the current text as std::string. | 207 // Returns the current text as std::string. |
| 208 std::string GetText(); | 208 std::string GetText(); |
| 209 | 209 |
| 210 // Set the selection range for the installed textfield. |
| 211 void SetSelectionRange(const gfx::Range& range); |
| 212 |
| 210 // testing::Test: | 213 // testing::Test: |
| 211 void SetUp() override; | 214 void SetUp() override; |
| 212 void TearDown() override; | 215 void TearDown() override; |
| 213 | 216 |
| 214 protected: | 217 protected: |
| 218 // Test delete to beginning of line or paragraph based on |sel|. |sel| can be |
| 219 // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:. |
| 220 void TestDeleteBeginning(SEL sel); |
| 221 |
| 222 // Test delete to end of line or paragraph based on |sel|. |sel| can be |
| 223 // either deleteToEndOfLine: or deleteToEndOfParagraph:. |
| 224 void TestDeleteEnd(SEL sel); |
| 225 |
| 215 std::unique_ptr<views::View> view_; | 226 std::unique_ptr<views::View> view_; |
| 216 BridgedContentView* ns_view_; // Weak. Owned by bridge(). | 227 BridgedContentView* ns_view_; // Weak. Owned by bridge(). |
| 217 base::MessageLoopForUI message_loop_; | 228 base::MessageLoopForUI message_loop_; |
| 218 | 229 |
| 219 private: | 230 private: |
| 220 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); | 231 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); |
| 221 }; | 232 }; |
| 222 | 233 |
| 223 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { | 234 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { |
| 224 } | 235 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 248 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); | 259 InstallTextField(text, ui::TEXT_INPUT_TYPE_TEXT); |
| 249 } | 260 } |
| 250 | 261 |
| 251 std::string BridgedNativeWidgetTest::GetText() { | 262 std::string BridgedNativeWidgetTest::GetText() { |
| 252 NSRange range = NSMakeRange(0, NSUIntegerMax); | 263 NSRange range = NSMakeRange(0, NSUIntegerMax); |
| 253 NSAttributedString* text = | 264 NSAttributedString* text = |
| 254 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL]; | 265 [ns_view_ attributedSubstringForProposedRange:range actualRange:NULL]; |
| 255 return SysNSStringToUTF8([text string]); | 266 return SysNSStringToUTF8([text string]); |
| 256 } | 267 } |
| 257 | 268 |
| 269 void BridgedNativeWidgetTest::SetSelectionRange(const gfx::Range& range) { |
| 270 ui::TextInputClient* client = [ns_view_ textInputClient]; |
| 271 client->SetSelectionRange(range); |
| 272 } |
| 273 |
| 258 void BridgedNativeWidgetTest::SetUp() { | 274 void BridgedNativeWidgetTest::SetUp() { |
| 259 BridgedNativeWidgetTestBase::SetUp(); | 275 BridgedNativeWidgetTestBase::SetUp(); |
| 260 | 276 |
| 261 view_.reset(new views::internal::RootView(widget_.get())); | 277 view_.reset(new views::internal::RootView(widget_.get())); |
| 262 base::scoped_nsobject<NSWindow> window([test_window() retain]); | 278 base::scoped_nsobject<NSWindow> window([test_window() retain]); |
| 263 | 279 |
| 264 // BridgedNativeWidget expects to be initialized with a hidden (deferred) | 280 // BridgedNativeWidget expects to be initialized with a hidden (deferred) |
| 265 // window. | 281 // window. |
| 266 [window orderOut:nil]; | 282 [window orderOut:nil]; |
| 267 EXPECT_FALSE([window delegate]); | 283 EXPECT_FALSE([window delegate]); |
| 268 bridge()->Init(window, init_params_); | 284 bridge()->Init(window, init_params_); |
| 269 | 285 |
| 270 // The delegate should exist before setting the root view. | 286 // The delegate should exist before setting the root view. |
| 271 EXPECT_TRUE([window delegate]); | 287 EXPECT_TRUE([window delegate]); |
| 272 bridge()->SetRootView(view_.get()); | 288 bridge()->SetRootView(view_.get()); |
| 273 ns_view_ = bridge()->ns_view(); | 289 ns_view_ = bridge()->ns_view(); |
| 274 | 290 |
| 275 // Pretend it has been shown via NativeWidgetMac::Show(). | 291 // Pretend it has been shown via NativeWidgetMac::Show(). |
| 276 [window orderFront:nil]; | 292 [window orderFront:nil]; |
| 277 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()]; | 293 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge()->ns_view()]; |
| 278 } | 294 } |
| 279 | 295 |
| 280 void BridgedNativeWidgetTest::TearDown() { | 296 void BridgedNativeWidgetTest::TearDown() { |
| 281 if (bridge()) | 297 if (bridge()) |
| 282 bridge()->SetRootView(nullptr); | 298 bridge()->SetRootView(nullptr); |
| 283 view_.reset(); | 299 view_.reset(); |
| 284 BridgedNativeWidgetTestBase::TearDown(); | 300 BridgedNativeWidgetTestBase::TearDown(); |
| 285 } | 301 } |
| 286 | 302 |
| 303 void BridgedNativeWidgetTest::TestDeleteBeginning(SEL sel) { |
| 304 InstallTextField("foo bar baz"); |
| 305 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 306 |
| 307 // Move the caret to the beginning of the line. |
| 308 SetSelectionRange(gfx::Range(0)); |
| 309 // Verify no deletion takes place. |
| 310 [ns_view_ doCommandBySelector:sel]; |
| 311 EXPECT_EQ("foo bar baz", GetText()); |
| 312 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 313 |
| 314 // Move the caret as- "foo| bar baz". |
| 315 SetSelectionRange(gfx::Range(3, 3)); |
| 316 [ns_view_ doCommandBySelector:sel]; |
| 317 // Verify state is "| bar baz". |
| 318 EXPECT_EQ(" bar baz", GetText()); |
| 319 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 320 |
| 321 // Make a selection as- " bar |baz|". |
| 322 SetSelectionRange(gfx::Range(5, 8)); |
| 323 [ns_view_ doCommandBySelector:sel]; |
| 324 // Verify only the selection is deleted so that the state is " bar |". |
| 325 EXPECT_EQ(" bar ", GetText()); |
| 326 EXPECT_EQ_RANGE(NSMakeRange(5, 0), [ns_view_ selectedRange]); |
| 327 } |
| 328 |
| 329 void BridgedNativeWidgetTest::TestDeleteEnd(SEL sel) { |
| 330 InstallTextField("foo bar baz"); |
| 331 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 332 |
| 333 // Caret is at the end of the line. Verify no deletion takes place. |
| 334 [ns_view_ doCommandBySelector:sel]; |
| 335 EXPECT_EQ("foo bar baz", GetText()); |
| 336 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 337 |
| 338 // Move the caret as- "foo bar| baz". |
| 339 SetSelectionRange(gfx::Range(7, 7)); |
| 340 [ns_view_ doCommandBySelector:sel]; |
| 341 // Verify state is "foo bar|". |
| 342 EXPECT_EQ("foo bar", GetText()); |
| 343 EXPECT_EQ_RANGE(NSMakeRange(7, 0), [ns_view_ selectedRange]); |
| 344 |
| 345 // Make a selection as- "|foo |bar". |
| 346 SetSelectionRange(gfx::Range(0, 4)); |
| 347 [ns_view_ doCommandBySelector:sel]; |
| 348 // Verify only the selection is deleted so that the state is "|bar". |
| 349 EXPECT_EQ("bar", GetText()); |
| 350 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 351 } |
| 352 |
| 287 // The TEST_VIEW macro expects the view it's testing to have a superview. In | 353 // The TEST_VIEW macro expects the view it's testing to have a superview. In |
| 288 // these tests, the NSView bridge is a contentView, at the root. These mimic | 354 // these tests, the NSView bridge is a contentView, at the root. These mimic |
| 289 // what TEST_VIEW usually does. | 355 // what TEST_VIEW usually does. |
| 290 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { | 356 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { |
| 291 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); | 357 base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]); |
| 292 EXPECT_NSEQ([test_window() contentView], view); | 358 EXPECT_NSEQ([test_window() contentView], view); |
| 293 EXPECT_NSEQ(test_window(), [view window]); | 359 EXPECT_NSEQ(test_window(), [view window]); |
| 294 | 360 |
| 295 // The superview of a contentView is an NSNextStepFrame. | 361 // The superview of a contentView is an NSNextStepFrame. |
| 296 EXPECT_TRUE([view superview]); | 362 EXPECT_TRUE([view superview]); |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 EXPECT_EQ("a", GetText()); | 644 EXPECT_EQ("a", GetText()); |
| 579 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); | 645 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); |
| 580 | 646 |
| 581 // Should succeed after moving left first. | 647 // Should succeed after moving left first. |
| 582 [ns_view_ doCommandBySelector:@selector(moveLeft:)]; | 648 [ns_view_ doCommandBySelector:@selector(moveLeft:)]; |
| 583 [ns_view_ doCommandBySelector:@selector(deleteForward:)]; | 649 [ns_view_ doCommandBySelector:@selector(deleteForward:)]; |
| 584 EXPECT_EQ("", GetText()); | 650 EXPECT_EQ("", GetText()); |
| 585 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); | 651 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 586 } | 652 } |
| 587 | 653 |
| 654 // Test forward word deletion using text input protocol. |
| 655 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordForward) { |
| 656 InstallTextField("foo bar baz"); |
| 657 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 658 |
| 659 // Caret is at the end of the line. Verify no deletion takes place. |
| 660 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)]; |
| 661 EXPECT_EQ("foo bar baz", GetText()); |
| 662 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 663 |
| 664 // Move the caret as- "foo b|ar baz". |
| 665 SetSelectionRange(gfx::Range(5, 5)); |
| 666 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)]; |
| 667 // Verify state is "foo b| baz" |
| 668 EXPECT_EQ("foo b baz", GetText()); |
| 669 EXPECT_EQ_RANGE(NSMakeRange(5, 0), [ns_view_ selectedRange]); |
| 670 |
| 671 // Make a selection as- "|fo|o b baz". |
| 672 SetSelectionRange(gfx::Range(0, 2)); |
| 673 [ns_view_ doCommandBySelector:@selector(deleteWordForward:)]; |
| 674 // Verify only the selection is deleted and state is "|o b baz". |
| 675 EXPECT_EQ("o b baz", GetText()); |
| 676 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 677 } |
| 678 |
| 679 // Test backward word deletion using text input protocol. |
| 680 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordBackward) { |
| 681 InstallTextField("foo bar baz"); |
| 682 EXPECT_EQ_RANGE(NSMakeRange(11, 0), [ns_view_ selectedRange]); |
| 683 |
| 684 // Move the caret to the beginning of the line. |
| 685 SetSelectionRange(gfx::Range(0)); |
| 686 // Verify no deletion takes place. |
| 687 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)]; |
| 688 EXPECT_EQ("foo bar baz", GetText()); |
| 689 EXPECT_EQ_RANGE(NSMakeRange(0, 0), [ns_view_ selectedRange]); |
| 690 |
| 691 // Move the caret as- "foo ba|r baz". |
| 692 SetSelectionRange(gfx::Range(6, 6)); |
| 693 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)]; |
| 694 // Verify state is "foo |r baz". |
| 695 EXPECT_EQ("foo r baz", GetText()); |
| 696 EXPECT_EQ_RANGE(NSMakeRange(4, 0), [ns_view_ selectedRange]); |
| 697 |
| 698 // Make a selection as- "f|oo r b|az". |
| 699 SetSelectionRange(gfx::Range(1, 7)); |
| 700 [ns_view_ doCommandBySelector:@selector(deleteWordBackward:)]; |
| 701 // Verify only the selection is deleted and state is "f|az" |
| 702 EXPECT_EQ("faz", GetText()); |
| 703 EXPECT_EQ_RANGE(NSMakeRange(1, 0), [ns_view_ selectedRange]); |
| 704 } |
| 705 |
| 706 // Test deleting to beginning/end of line/paragraph using text input protocol. |
| 707 |
| 708 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfLine) { |
| 709 TestDeleteBeginning(@selector(deleteToBeginningOfLine:)); |
| 710 } |
| 711 |
| 712 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfLine) { |
| 713 TestDeleteEnd(@selector(deleteToEndOfLine:)); |
| 714 } |
| 715 |
| 716 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) { |
| 717 TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:)); |
| 718 } |
| 719 |
| 720 TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) { |
| 721 TestDeleteEnd(@selector(deleteToEndOfParagraph:)); |
| 722 } |
| 723 |
| 588 // Test firstRectForCharacterRange:actualRange for cases where query range is | 724 // Test firstRectForCharacterRange:actualRange for cases where query range is |
| 589 // empty or outside composition range. | 725 // empty or outside composition range. |
| 590 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) { | 726 TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) { |
| 591 InstallTextField(""); | 727 InstallTextField(""); |
| 592 ui::TextInputClient* client = [ns_view_ textInputClient]; | 728 ui::TextInputClient* client = [ns_view_ textInputClient]; |
| 593 | 729 |
| 594 // No composition. Ensure bounds and range corresponding to the current caret | 730 // No composition. Ensure bounds and range corresponding to the current caret |
| 595 // position are returned. | 731 // position are returned. |
| 596 // Initially selection range will be [0, 0]. | 732 // Initially selection range will be [0, 0]. |
| 597 NSRange caret_range = NSMakeRange(0, 0); | 733 NSRange caret_range = NSMakeRange(0, 0); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 [center postNotificationName:NSWindowDidExitFullScreenNotification | 878 [center postNotificationName:NSWindowDidExitFullScreenNotification |
| 743 object:window]; | 879 object:window]; |
| 744 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. | 880 EXPECT_EQ(1, [window ignoredToggleFullScreenCount]); // No change. |
| 745 EXPECT_FALSE(bridge()->target_fullscreen_state()); | 881 EXPECT_FALSE(bridge()->target_fullscreen_state()); |
| 746 | 882 |
| 747 widget_->CloseNow(); | 883 widget_->CloseNow(); |
| 748 } | 884 } |
| 749 | 885 |
| 750 } // namespace test | 886 } // namespace test |
| 751 } // namespace views | 887 } // namespace views |
| OLD | NEW |