summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-20 23:04:52 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-20 23:04:52 +0000
commit2f2c514a8badf31de45402e7216947c6b10620af (patch)
treea04b5df367c7b23c9c12e4e5d98590ac6d1d126b /chrome/browser/cocoa
parent5b5ca7cb9e35732577c335a1ec3eaa7833224b2e (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.h11
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.mm8
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor.h15
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor.mm15
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor_unittest.mm106
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_unittest.mm50
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