diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-20 23:04:52 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-20 23:04:52 +0000 |
commit | 2f2c514a8badf31de45402e7216947c6b10620af (patch) | |
tree | a04b5df367c7b23c9c12e4e5d98590ac6d1d126b /chrome/browser/cocoa | |
parent | 5b5ca7cb9e35732577c335a1ec3eaa7833224b2e (diff) | |
download | chromium_src-2f2c514a8badf31de45402e7216947c6b10620af.zip chromium_src-2f2c514a8badf31de45402e7216947c6b10620af.tar.gz chromium_src-2f2c514a8badf31de45402e7216947c6b10620af.tar.bz2 |
[Mac] Strip newlines from paste.
http://crbug.com/11817
TEST=Copy an URL somewhere and break it apart with newlines at random places. Copy/paste it into omnibox and the newlines should be gone. Try this one:
http://dev.chro
mium.org/develo
pers/how-tos/ge
t-the-code
Review URL: http://codereview.chromium.org/159018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
6 files changed, 189 insertions, 16 deletions
diff --git a/chrome/browser/cocoa/autocomplete_text_field.h b/chrome/browser/cocoa/autocomplete_text_field.h index 709bd17..17025d2 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.h +++ b/chrome/browser/cocoa/autocomplete_text_field.h @@ -12,8 +12,19 @@ // around this code all at once before layering other changes over in // parallel. +@protocol AutocompleteTextFieldDelegateMethods + +// Delegate -textShouldPaste: implementation to the field being +// edited. See AutocompleteTextFieldEditor implementation. +- (BOOL)control:(NSControl*)control textShouldPaste:(NSText*)fieldEditor; + +@end + @interface AutocompleteTextField : NSTextField { } + +- (BOOL)textShouldPaste:(NSText*)fieldEditor; + @end #endif // CHROME_BROWSER_COCOA_AUTOCOMPLETE_TEXT_FIELD_H_ diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm index 0efb310a..6d1d5d5 100644 --- a/chrome/browser/cocoa/autocomplete_text_field.mm +++ b/chrome/browser/cocoa/autocomplete_text_field.mm @@ -17,4 +17,12 @@ DCHECK([[self cell] isKindOfClass:[AutocompleteTextFieldCell class]]); } +- (BOOL)textShouldPaste:(NSText*)fieldEditor { + id delegate = [self delegate]; + if ([delegate respondsToSelector:@selector(control:textShouldPaste:)]) { + return [delegate control:self textShouldPaste:fieldEditor]; + } + return YES; +} + @end diff --git a/chrome/browser/cocoa/autocomplete_text_field_editor.h b/chrome/browser/cocoa/autocomplete_text_field_editor.h index 1d4d073..640bb9b 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_editor.h +++ b/chrome/browser/cocoa/autocomplete_text_field_editor.h @@ -4,6 +4,16 @@ #import <Cocoa/Cocoa.h> +@protocol AutocompleteTextFieldEditorDelegateMethods + +// Delegate -paste: implementation to the field being edited. If the +// delegate returns YES, or does not implement the method, NSTextView +// is called to handle the paste. The delegate can block the paste +// (or handle it internally) by returning NO. +- (BOOL)textShouldPaste:(NSText*)fieldEditor; + +@end + // Field editor used for the autocomplete field. @interface AutocompleteTextFieldEditor : NSTextView { } @@ -14,4 +24,9 @@ // Same as above, note that this calls through to performCopy. - (void)performCut:(NSPasteboard*)pb; + +// Called by -paste: to decide whether to forward to superclass. +// Exposed for unit testing. +- (BOOL)shouldPaste; + @end diff --git a/chrome/browser/cocoa/autocomplete_text_field_editor.mm b/chrome/browser/cocoa/autocomplete_text_field_editor.mm index 4c29bb3..6e08a6c 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_editor.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_editor.mm @@ -30,4 +30,19 @@ [self delete:nil]; } +- (BOOL)shouldPaste { + id delegate = [self delegate]; + if (![delegate respondsToSelector:@selector(textShouldPaste:)] || + [delegate textShouldPaste:self]) { + return YES; + } + return NO; +} + +- (void)paste:(id)sender { + if ([self shouldPaste]) { + [super paste:sender]; + } +} + @end diff --git a/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm index 71314cf..7e33bc1 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm @@ -7,9 +7,18 @@ #include "base/scoped_nsobject.h" #include "base/scoped_ptr.h" #include "base/string_util.h" +#import "chrome/browser/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" +@interface AutocompleteTextFieldEditorTestDelegate : NSObject { + BOOL textShouldPaste_; + BOOL receivedTextShouldPaste_; +} +- initWithTextShouldPaste:(BOOL)flag; +- (BOOL)receivedTextShouldPaste; +@end + namespace { int NumTypesOnPasteboard(NSPasteboard* pb) { return [[pb types] count]; @@ -30,10 +39,15 @@ bool ClipboardContainsText(NSPasteboard* pb, NSString* cmp) { return [clipboard_text isEqualToString:cmp]; } -} // namespace - class AutocompleteTextFieldEditorTest : public PlatformTest { public: + AutocompleteTextFieldEditorTest() { + NSRect frame = NSMakeRect(0, 0, 50, 30); + editor_.reset([[AutocompleteTextFieldEditor alloc] initWithFrame:frame]); + [editor_ setString:@"Testing"]; + [cocoa_helper_.contentView() addSubview:editor_.get()]; + } + virtual void SetUp() { PlatformTest::SetUp(); pb_ = [NSPasteboard pasteboardWithUniqueName]; @@ -50,8 +64,11 @@ class AutocompleteTextFieldEditorTest : public PlatformTest { return pb_; } - private: - NSPasteboard *pb_; + CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... + scoped_nsobject<AutocompleteTextFieldEditor> editor_; + + private: + NSPasteboard *pb_; }; TEST_F(AutocompleteTextFieldEditorTest, CutCopyTest) { @@ -61,28 +78,85 @@ TEST_F(AutocompleteTextFieldEditorTest, CutCopyTest) { NSString* test_string_1 = @"astring"; NSString* test_string_2 = @"another string"; - scoped_nsobject<AutocompleteTextFieldEditor> field_editor( - [[AutocompleteTextFieldEditor alloc] init]); - [field_editor.get() setRichText:YES]; + [editor_.get() setRichText:YES]; // Put some text on the clipboard. - [field_editor.get() setString:test_string_1]; - [field_editor.get() selectAll:nil]; - [field_editor.get() alignRight:nil]; // Add a rich text attribute. + [editor_.get() setString:test_string_1]; + [editor_.get() selectAll:nil]; + [editor_.get() alignRight:nil]; // Add a rich text attribute. ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); // Check that copying it works and we only get plain text. NSPasteboard* pb = clipboard(); - [field_editor.get() performCopy:pb]; + [editor_.get() performCopy:pb]; ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_1)); // Check that cutting it works and we only get plain text. - [field_editor.get() setString:test_string_2]; - [field_editor.get() selectAll:nil]; - [field_editor.get() alignLeft:nil]; // Add a rich text attribute. - [field_editor.get() performCut:pb]; + [editor_.get() setString:test_string_2]; + [editor_.get() selectAll:nil]; + [editor_.get() alignLeft:nil]; // Add a rich text attribute. + [editor_.get() performCut:pb]; ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_2)); - ASSERT_EQ([[field_editor.get() textStorage] length], 0U); + ASSERT_EQ([[editor_.get() textStorage] length], 0U); +} + +// Test adding/removing from the view hierarchy, mostly to ensure nothing +// leaks or crashes. +TEST_F(AutocompleteTextFieldEditorTest, AddRemove) { + EXPECT_EQ(cocoa_helper_.contentView(), [editor_ superview]); + [editor_.get() removeFromSuperview]; + EXPECT_FALSE([editor_ superview]); +} + +// Test drawing, mostly to ensure nothing leaks or crashes. +TEST_F(AutocompleteTextFieldEditorTest, Display) { + [editor_ display]; +} + +// Test that -shouldPaste properly queries the delegate. +TEST_F(AutocompleteTextFieldEditorTest, TextShouldPaste) { + EXPECT_TRUE(![editor_ delegate]); + EXPECT_TRUE([editor_ shouldPaste]); + + scoped_nsobject<AutocompleteTextFieldEditorTestDelegate> shouldPaste( + [[AutocompleteTextFieldEditorTestDelegate alloc] + initWithTextShouldPaste:YES]); + [editor_ setDelegate:shouldPaste]; + EXPECT_FALSE([shouldPaste receivedTextShouldPaste]); + EXPECT_TRUE([editor_ shouldPaste]); + EXPECT_TRUE([shouldPaste receivedTextShouldPaste]); + + scoped_nsobject<AutocompleteTextFieldEditorTestDelegate> shouldNotPaste( + [[AutocompleteTextFieldEditorTestDelegate alloc] + initWithTextShouldPaste:NO]); + [editor_ setDelegate:shouldNotPaste]; + EXPECT_FALSE([shouldNotPaste receivedTextShouldPaste]); + EXPECT_FALSE([editor_ shouldPaste]); + EXPECT_TRUE([shouldNotPaste receivedTextShouldPaste]); +} + +} // namespace + +@implementation AutocompleteTextFieldEditorTestDelegate + +- initWithTextShouldPaste:(BOOL)flag { + self = [super init]; + if (self) { + textShouldPaste_ = flag; + receivedTextShouldPaste_ = NO; + } + return self; +} + +- (BOOL)receivedTextShouldPaste { + return receivedTextShouldPaste_; } + +- (BOOL)textShouldPaste:(NSText*)fieldEditor { + receivedTextShouldPaste_ = YES; + return textShouldPaste_; +} + +@end diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm index 9e861a8..03a786f 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm @@ -10,6 +10,14 @@ #import "chrome/browser/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" +@interface AutocompleteTextFieldTestDelegate : NSObject { + BOOL textShouldPaste_; + BOOL receivedTextShouldPaste_; +} +- initWithTextShouldPaste:(BOOL)flag; +- (BOOL)receivedTextShouldPaste; +@end + namespace { class AutocompleteTextFieldTest : public testing::Test { @@ -43,4 +51,46 @@ TEST_F(AutocompleteTextFieldTest, Display) { [field_ display]; } +// Test that -textShouldPaste: properly queries the delegate. +TEST_F(AutocompleteTextFieldTest, TextShouldPaste) { + EXPECT_TRUE(![field_ delegate]); + EXPECT_TRUE([field_ textShouldPaste:nil]); + + scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldPaste( + [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:YES]); + [field_ setDelegate:shouldPaste]; + EXPECT_FALSE([shouldPaste receivedTextShouldPaste]); + EXPECT_TRUE([field_ textShouldPaste:nil]); + EXPECT_TRUE([shouldPaste receivedTextShouldPaste]); + + scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldNotPaste( + [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]); + [field_ setDelegate:shouldNotPaste]; + EXPECT_FALSE([shouldNotPaste receivedTextShouldPaste]); + EXPECT_FALSE([field_ textShouldPaste:nil]); + EXPECT_TRUE([shouldNotPaste receivedTextShouldPaste]); +} + } // namespace + +@implementation AutocompleteTextFieldTestDelegate + +- initWithTextShouldPaste:(BOOL)flag { + self = [super init]; + if (self) { + textShouldPaste_ = flag; + receivedTextShouldPaste_ = NO; + } + return self; +} + +- (BOOL)receivedTextShouldPaste { + return receivedTextShouldPaste_; +} + +- (BOOL)control:(NSControl*)control textShouldPaste:(NSText*)fieldEditor { + receivedTextShouldPaste_ = YES; + return textShouldPaste_; +} + +@end |