Commit aee23654 authored by kushi.p@gmail.com's avatar kushi.p@gmail.com

Do not allow multiline input when naming bookmark folders on Mac

- the respective nibs now use Single Line Mode for title entry
- BookmarkModel has been updated (with test cases) to strip extra whitespace for folder/bookmark titles.

BUG=100618
TEST=BookmarkModelTest.AddURLWithWhitespaceTitle, BookmarkModelTest.AddFolderWithWhitespaceTitle, BookmarkModelTest.SetTitleWithWhitespace

Review URL: http://codereview.chromium.org/8598015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112400 0039d316-1c4b-4281-b951-d872f2087c98
parent 7e0dca19
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/string_util.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h" #include "chrome/browser/bookmarks/bookmark_expanded_state_tracker.h"
#include "chrome/browser/bookmarks/bookmark_index.h" #include "chrome/browser/bookmarks/bookmark_index.h"
...@@ -305,11 +306,14 @@ const SkBitmap& BookmarkModel::GetFavicon(const BookmarkNode* node) { ...@@ -305,11 +306,14 @@ const SkBitmap& BookmarkModel::GetFavicon(const BookmarkNode* node) {
} }
void BookmarkModel::SetTitle(const BookmarkNode* node, const string16& title) { void BookmarkModel::SetTitle(const BookmarkNode* node, const string16& title) {
// Remove extra whitespace from folder/bookmark names.
string16 mutable_title = CollapseWhitespace(title, false);
if (!node) { if (!node) {
NOTREACHED(); NOTREACHED();
return; return;
} }
if (node->GetTitle() == title) if (node->GetTitle() == mutable_title)
return; return;
if (is_permanent_node(node)) { if (is_permanent_node(node)) {
...@@ -320,7 +324,7 @@ void BookmarkModel::SetTitle(const BookmarkNode* node, const string16& title) { ...@@ -320,7 +324,7 @@ void BookmarkModel::SetTitle(const BookmarkNode* node, const string16& title) {
// The title index doesn't support changing the title, instead we remove then // The title index doesn't support changing the title, instead we remove then
// add it back. // add it back.
index_->Remove(node); index_->Remove(node);
AsMutable(node)->set_title(title); AsMutable(node)->set_title(mutable_title);
index_->Add(node); index_->Add(node);
if (store_.get()) if (store_.get())
...@@ -436,7 +440,8 @@ const BookmarkNode* BookmarkModel::AddFolder(const BookmarkNode* parent, ...@@ -436,7 +440,8 @@ const BookmarkNode* BookmarkModel::AddFolder(const BookmarkNode* parent,
BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), GURL()); BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), GURL());
new_node->set_date_folder_modified(Time::Now()); new_node->set_date_folder_modified(Time::Now());
new_node->set_title(title); // Folders shouldn't have line breaks in their titles.
new_node->set_title(CollapseWhitespace(title, false));
new_node->set_type(BookmarkNode::FOLDER); new_node->set_type(BookmarkNode::FOLDER);
return AddNode(AsMutable(parent), index, new_node, false); return AddNode(AsMutable(parent), index, new_node, false);
...@@ -446,7 +451,9 @@ const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent, ...@@ -446,7 +451,9 @@ const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent,
int index, int index,
const string16& title, const string16& title,
const GURL& url) { const GURL& url) {
return AddURLWithCreationTime(parent, index, title, url, Time::Now()); return AddURLWithCreationTime(parent, index,
CollapseWhitespace(title, false),
url, Time::Now());
} }
const BookmarkNode* BookmarkModel::AddURLWithCreationTime( const BookmarkNode* BookmarkModel::AddURLWithCreationTime(
......
...@@ -41,6 +41,35 @@ using content::BrowserThread; ...@@ -41,6 +41,35 @@ using content::BrowserThread;
namespace { namespace {
// Test cases used to test the removal of extra whitespace when adding
// a new folder/bookmark or updating a title of a folder/bookmark.
static struct {
const std::string input_title;
const std::string expected_title;
} whitespace_test_cases[] = {
{"foobar", "foobar"},
// Newlines.
{"foo\nbar", "foo bar"},
{"foo\n\nbar", "foo bar"},
{"foo\n\n\nbar", "foo bar"},
{"foo\r\nbar", "foo bar"},
{"foo\r\n\r\nbar", "foo bar"},
{"\nfoo\nbar\n", "foo bar"},
// Spaces.
{"foo bar", "foo bar"},
{" foo bar ", "foo bar"},
{" foo bar ", "foo bar"},
// Tabs.
{"\tfoo\tbar\t", "foo bar"},
{"\tfoo bar\t", "foo bar"},
// Mixed cases.
{"\tfoo\nbar\t", "foo bar"},
{"\tfoo\r\nbar\t", "foo bar"},
{" foo\tbar\n", "foo bar"},
{"\t foo \t bar \t", "foo bar"},
{"\n foo\r\n\tbar\n \t", "foo bar"},
};
// Helper to get a mutable bookmark node. // Helper to get a mutable bookmark node.
BookmarkNode* AsMutable(const BookmarkNode* node) { BookmarkNode* AsMutable(const BookmarkNode* node) {
return const_cast<BookmarkNode*>(node); return const_cast<BookmarkNode*>(node);
...@@ -212,6 +241,22 @@ TEST_F(BookmarkModelTest, AddURL) { ...@@ -212,6 +241,22 @@ TEST_F(BookmarkModelTest, AddURL) {
new_node->id() != model_.synced_node()->id()); new_node->id() != model_.synced_node()->id());
} }
TEST_F(BookmarkModelTest, AddURLWithWhitespaceTitle) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i) {
const BookmarkNode* root = model_.bookmark_bar_node();
const string16 title(ASCIIToUTF16(whitespace_test_cases[i].input_title));
const GURL url("http://foo.com");
const BookmarkNode* new_node = model_.AddURL(root, i, title, url);
int size = i + 1;
EXPECT_EQ(size, root->child_count());
EXPECT_EQ(ASCIIToUTF16(whitespace_test_cases[i].expected_title),
new_node->GetTitle());
EXPECT_EQ(BookmarkNode::URL, new_node->type());
}
}
TEST_F(BookmarkModelTest, AddURLToSyncedBookmarks) { TEST_F(BookmarkModelTest, AddURLToSyncedBookmarks) {
const BookmarkNode* root = model_.synced_node(); const BookmarkNode* root = model_.synced_node();
const string16 title(ASCIIToUTF16("foo")); const string16 title(ASCIIToUTF16("foo"));
...@@ -255,6 +300,21 @@ TEST_F(BookmarkModelTest, AddFolder) { ...@@ -255,6 +300,21 @@ TEST_F(BookmarkModelTest, AddFolder) {
observer_details_.ExpectEquals(root, NULL, 0, -1); observer_details_.ExpectEquals(root, NULL, 0, -1);
} }
TEST_F(BookmarkModelTest, AddFolderWithWhitespaceTitle) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i) {
const BookmarkNode* root = model_.bookmark_bar_node();
const string16 title(ASCIIToUTF16(whitespace_test_cases[i].input_title));
const BookmarkNode* new_node = model_.AddFolder(root, i, title);
int size = i + 1;
EXPECT_EQ(size, root->child_count());
EXPECT_EQ(ASCIIToUTF16(whitespace_test_cases[i].expected_title),
new_node->GetTitle());
EXPECT_EQ(BookmarkNode::FOLDER, new_node->type());
}
}
TEST_F(BookmarkModelTest, RemoveURL) { TEST_F(BookmarkModelTest, RemoveURL) {
const BookmarkNode* root = model_.bookmark_bar_node(); const BookmarkNode* root = model_.bookmark_bar_node();
const string16 title(ASCIIToUTF16("foo")); const string16 title(ASCIIToUTF16("foo"));
...@@ -309,6 +369,20 @@ TEST_F(BookmarkModelTest, SetTitle) { ...@@ -309,6 +369,20 @@ TEST_F(BookmarkModelTest, SetTitle) {
EXPECT_EQ(title, node->GetTitle()); EXPECT_EQ(title, node->GetTitle());
} }
TEST_F(BookmarkModelTest, SetTitleWithWhitespace) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i) {
const BookmarkNode* root = model_.bookmark_bar_node();
string16 title(ASCIIToUTF16("dummy"));
const GURL url("http://foo.com");
const BookmarkNode* node = model_.AddURL(root, 0, title, url);
title = ASCIIToUTF16(whitespace_test_cases[i].input_title);
model_.SetTitle(node, title);
EXPECT_EQ(ASCIIToUTF16(whitespace_test_cases[i].expected_title),
node->GetTitle());
}
}
TEST_F(BookmarkModelTest, SetURL) { TEST_F(BookmarkModelTest, SetURL) {
const BookmarkNode* root = model_.bookmark_bar_node(); const BookmarkNode* root = model_.bookmark_bar_node();
const string16 title(ASCIIToUTF16("foo")); const string16 title(ASCIIToUTF16("foo"));
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_CELL_SINGLE_LINE_H_
#define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_CELL_SINGLE_LINE_H_
#pragma once
#import <Cocoa/Cocoa.h>
// Provides a category for 10.5 compilation of a selector which is only
// available on 10.6+. This purely enables compilation when the selector
// is present and does not implement the method itself.
@interface NSCell(multilinebookmarks)
- (void)setUsesSingleLineMode:(BOOL)flag;
@end
#endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_CELL_SINGLE_LINE_H_
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_cell_single_line.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_tree_browser_cell.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h"
...@@ -564,6 +565,14 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver { ...@@ -564,6 +565,14 @@ class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver {
[self setTableSelectionPath:selection]; [self setTableSelectionPath:selection];
NSInteger row = [folderTreeView_ selectedRow]; NSInteger row = [folderTreeView_ selectedRow];
DCHECK(row >= 0); DCHECK(row >= 0);
// Put the cell into single-line mode before putting it into edit mode.
NSCell* folderCell = [folderTreeView_ preparedCellAtColumn:0 row:row];
if ([folderCell
respondsToSelector:@selector(setUsesSingleLineMode:)]) {
[folderCell setUsesSingleLineMode:YES];
}
[folderTreeView_ editColumn:0 row:row withEvent:nil select:YES]; [folderTreeView_ editColumn:0 row:row withEvent:nil select:YES];
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "base/sys_string_conversions.h" #include "base/sys_string_conversions.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_cell_single_line.h"
#include "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h" #include "chrome/browser/ui/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -68,6 +69,14 @@ ...@@ -68,6 +69,14 @@
- (void)awakeFromNib { - (void)awakeFromNib {
[nameField_ setStringValue:initialName_.get()]; [nameField_ setStringValue:initialName_.get()];
// Check if NSTextFieldCell supports the method. This check is in place as
// only 10.6 and greater support the setUsesSingleLineMode method.
NSTextFieldCell* nameFieldCell_ = [nameField_ cell];
if ([nameFieldCell_
respondsToSelector:@selector(setUsesSingleLineMode:)]) {
[nameFieldCell_ setUsesSingleLineMode:YES];
}
} }
- (void)runAsModalSheet { - (void)runAsModalSheet {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment