summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/bookmarks
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa/bookmarks')
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h46
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.mm88
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm82
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h60
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.mm82
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm135
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h38
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h399
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm2497
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_controller_unittest.mm2169
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h31
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm22
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm24
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h182
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm1459
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm1552
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h78
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm171
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state_unittest.mm77
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h29
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.mm204
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm211
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h34
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.mm136
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm49
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_state.h62
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h44
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.mm135
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm191
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h57
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.mm81
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_view.h41
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_view.mm259
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bar_view_unittest.mm215
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h81
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.mm428
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm490
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button.h243
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button.mm238
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button_cell.h65
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button_cell.mm246
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button_cell_unittest.mm183
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_button_unittest.mm174
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_drag_source.h30
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_drag_source.mm43
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h171
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.mm604
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm235
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h36
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_controller.mm143
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_editor_controller_unittest.mm423
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_folder_target.h50
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_folder_target.mm118
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_folder_target_unittest.mm125
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu.h20
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu.mm22
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h123
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.mm253
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm317
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h46
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm98
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm66
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_menu_unittest.mm29
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h116
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm68
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h64
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.mm123
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm172
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h35
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.mm23
-rw-r--r--chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm43
71 files changed, 0 insertions, 16684 deletions
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h
deleted file mode 100644
index 4c6a57c..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_ALL_TABS_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_ALL_TABS_CONTROLLER_H_
-#pragma once
-
-#include <utility>
-#include <vector>
-
-#include "base/string16.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h"
-
-// A list of pairs containing the name and URL associated with each
-// currently active tab in the active browser window.
-typedef std::pair<string16, GURL> ActiveTabNameURLPair;
-typedef std::vector<ActiveTabNameURLPair> ActiveTabsNameURLPairVector;
-
-// A controller for the Bookmark All Tabs sheet which is presented upon
-// selecting the Bookmark All Tabs... menu item shown by the contextual
-// menu in the bookmarks bar.
-@interface BookmarkAllTabsController : BookmarkEditorBaseController {
- @private
- ActiveTabsNameURLPairVector activeTabPairsVector_;
-}
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- configuration:(BookmarkEditor::Configuration)configuration;
-
-@end
-
-@interface BookmarkAllTabsController(TestingAPI)
-
-// Initializes the list of all tab names and URLs. Overridden by unit test
-// to provide canned test data.
-- (void)UpdateActiveTabPairs;
-
-// Provides testing access to tab pairs list.
-- (ActiveTabsNameURLPairVector*)activeTabPairsVector;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_ALL_TABS_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.mm
deleted file mode 100644
index 961d37a..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.mm
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h"
-
-#include "app/l10n_util_mac.h"
-#include "base/string16.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "grit/generated_resources.h"
-
-@implementation BookmarkAllTabsController
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- configuration:(BookmarkEditor::Configuration)configuration {
- NSString* nibName = @"BookmarkAllTabs";
- if ((self = [super initWithParentWindow:parentWindow
- nibName:nibName
- profile:profile
- parent:parent
- configuration:configuration])) {
- }
- return self;
-}
-
-- (void)awakeFromNib {
- [self setInitialName:
- l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME)];
- [super awakeFromNib];
-}
-
-#pragma mark Bookmark Editing
-
-- (void)UpdateActiveTabPairs {
- activeTabPairsVector_.clear();
- Browser* browser = BrowserList::GetLastActive();
- TabStripModel* tabstrip_model = browser->tabstrip_model();
- const int tabCount = tabstrip_model->count();
- for (int i = 0; i < tabCount; ++i) {
- TabContents* tc = tabstrip_model->GetTabContentsAt(i)->tab_contents();
- const string16 tabTitle = tc->GetTitle();
- const GURL& tabURL(tc->GetURL());
- ActiveTabNameURLPair tabPair(tabTitle, tabURL);
- activeTabPairsVector_.push_back(tabPair);
- }
-}
-
-// Called by -[BookmarkEditorBaseController ok:]. Creates the container
-// folder for the tabs and then the bookmarks in that new folder.
-// Returns a BOOL as an NSNumber indicating that the commit may proceed.
-- (NSNumber*)didCommit {
- NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
- [NSCharacterSet newlineCharacterSet]];
- std::wstring newTitle = base::SysNSStringToWide(name);
- const BookmarkNode* newParentNode = [self selectedNode];
- int newIndex = newParentNode->GetChildCount();
- // Create the new folder which will contain all of the tab URLs.
- NSString* newFolderName = [self displayName];
- string16 newFolderString = base::SysNSStringToUTF16(newFolderName);
- BookmarkModel* model = [self bookmarkModel];
- const BookmarkNode* newFolder = model->AddGroup(newParentNode, newIndex,
- newFolderString);
- // Get a list of all open tabs, create nodes for them, and add
- // to the new folder node.
- [self UpdateActiveTabPairs];
- int i = 0;
- for (ActiveTabsNameURLPairVector::const_iterator it =
- activeTabPairsVector_.begin();
- it != activeTabPairsVector_.end(); ++it, ++i) {
- model->AddURL(newFolder, i, it->first, it->second);
- }
- return [NSNumber numberWithBool:YES];
-}
-
-- (ActiveTabsNameURLPairVector*)activeTabPairsVector {
- return &activeTabPairsVector_;
-}
-
-@end // BookmarkAllTabsController
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm
deleted file mode 100644
index 2fb42f0..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-@interface BookmarkAllTabsControllerOverride : BookmarkAllTabsController
-@end
-
-@implementation BookmarkAllTabsControllerOverride
-
-- (void)UpdateActiveTabPairs {
- ActiveTabsNameURLPairVector* activeTabPairsVector =
- [self activeTabPairsVector];
- activeTabPairsVector->clear();
- activeTabPairsVector->push_back(
- ActiveTabNameURLPair(ASCIIToUTF16("at-0"), GURL("http://at-0.com")));
- activeTabPairsVector->push_back(
- ActiveTabNameURLPair(ASCIIToUTF16("at-1"), GURL("http://at-1.com")));
- activeTabPairsVector->push_back(
- ActiveTabNameURLPair(ASCIIToUTF16("at-2"), GURL("http://at-2.com")));
-}
-
-@end
-
-class BookmarkAllTabsControllerTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
- const BookmarkNode* parent_node_;
- BookmarkAllTabsControllerOverride* controller_;
- const BookmarkNode* group_a_;
-
- BookmarkAllTabsControllerTest() {
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
- const BookmarkNode* root = model.GetBookmarkBarNode();
- group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a"));
- model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com"));
- model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com"));
- model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com"));
- }
-
- virtual BookmarkAllTabsControllerOverride* CreateController() {
- return [[BookmarkAllTabsControllerOverride alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:group_a_
- configuration:BookmarkEditor::SHOW_TREE];
- }
-
- virtual void SetUp() {
- CocoaTest::SetUp();
- controller_ = CreateController();
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-};
-
-TEST_F(BookmarkAllTabsControllerTest, BookmarkAllTabs) {
- // OK button should always be enabled.
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ selectTestNodeInBrowser:group_a_];
- [controller_ setDisplayName:@"ALL MY TABS"];
- [controller_ ok:nil];
- EXPECT_EQ(4, group_a_->GetChildCount());
- const BookmarkNode* folderChild = group_a_->GetChild(3);
- EXPECT_EQ(folderChild->GetTitle(), ASCIIToUTF16("ALL MY TABS"));
- EXPECT_EQ(3, folderChild->GetChildCount());
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h
deleted file mode 100644
index a0bc1a7..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2010 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.
-
-// C++ bridge class between Chromium and Cocoa to connect the
-// Bookmarks (model) with the Bookmark Bar (view).
-//
-// There is exactly one BookmarkBarBridge per BookmarkBarController /
-// BrowserWindowController / Browser.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_BRIDGE_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_BRIDGE_H_
-#pragma once
-
-#include "base/basictypes.h"
-#include "chrome/browser/bookmarks/bookmark_model_observer.h"
-
-class Browser;
-@class BookmarkBarController;
-
-class BookmarkBarBridge : public BookmarkModelObserver {
- public:
- BookmarkBarBridge(BookmarkBarController* controller,
- BookmarkModel* model);
- virtual ~BookmarkBarBridge();
-
- // Overridden from BookmarkModelObserver
- virtual void Loaded(BookmarkModel* model);
- virtual void BookmarkModelBeingDeleted(BookmarkModel* model);
- virtual void BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index);
- virtual void BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index);
- virtual void BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node);
- virtual void BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node);
- virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node);
- virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
- const BookmarkNode* node);
-
- virtual void BookmarkImportBeginning(BookmarkModel* model);
- virtual void BookmarkImportEnding(BookmarkModel* model);
-
- private:
- BookmarkBarController* controller_; // weak; owns me
- BookmarkModel* model_; // weak; it is owned by a Profile.
- bool batch_mode_;
-
- DISALLOW_COPY_AND_ASSIGN(BookmarkBarBridge);
-};
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_BRIDGE_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.mm
deleted file mode 100644
index dc38b91..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.mm
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h"
-
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-
-BookmarkBarBridge::BookmarkBarBridge(BookmarkBarController* controller,
- BookmarkModel* model)
- : controller_(controller),
- model_(model),
- batch_mode_(false) {
- model_->AddObserver(this);
-
- // Bookmark loading is async; it may may not have happened yet.
- // We will be notified when that happens with the AddObserver() call.
- if (model->IsLoaded())
- Loaded(model);
-}
-
-BookmarkBarBridge::~BookmarkBarBridge() {
- model_->RemoveObserver(this);
-}
-
-void BookmarkBarBridge::Loaded(BookmarkModel* model) {
- [controller_ loaded:model];
-}
-
-void BookmarkBarBridge::BookmarkModelBeingDeleted(BookmarkModel* model) {
- [controller_ beingDeleted:model];
-}
-
-void BookmarkBarBridge::BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index) {
- [controller_ nodeMoved:model
- oldParent:old_parent oldIndex:old_index
- newParent:new_parent newIndex:new_index];
-}
-
-void BookmarkBarBridge::BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index) {
- if (!batch_mode_) {
- [controller_ nodeAdded:model parent:parent index:index];
- }
-}
-
-void BookmarkBarBridge::BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node) {
- [controller_ nodeRemoved:model parent:parent index:old_index];
-}
-
-void BookmarkBarBridge::BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node) {
- [controller_ nodeChanged:model node:node];
-}
-
-void BookmarkBarBridge::BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node) {
- [controller_ nodeFavIconLoaded:model node:node];
-}
-
-void BookmarkBarBridge::BookmarkNodeChildrenReordered(
- BookmarkModel* model, const BookmarkNode* node) {
- [controller_ nodeChildrenReordered:model node:node];
-}
-
-void BookmarkBarBridge::BookmarkImportBeginning(BookmarkModel* model) {
- batch_mode_ = true;
-}
-
-void BookmarkBarBridge::BookmarkImportEnding(BookmarkModel* model) {
- batch_mode_ = false;
- [controller_ loaded:model];
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
deleted file mode 100644
index 567761e..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#include "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-// TODO(jrg): use OCMock.
-
-namespace {
-
-// Information needed to open a URL, as passed to the
-// BookmarkBarController's delegate.
-typedef std::pair<GURL,WindowOpenDisposition> OpenInfo;
-
-} // The namespace must end here -- I need to use OpenInfo in
- // FakeBookmarkBarController but can't place
- // FakeBookmarkBarController itself in the namespace ("error:
- // Objective-C declarations may only appear in global scope")
-
-// Oddly, we are our own delegate.
-@interface FakeBookmarkBarController : BookmarkBarController {
- @public
- scoped_nsobject<NSMutableArray> callbacks_;
- std::vector<OpenInfo> opens_;
-}
-@end
-
-@implementation FakeBookmarkBarController
-
-- (id)initWithBrowser:(Browser*)browser {
- if ((self = [super initWithBrowser:browser
- initialWidth:100 // arbitrary
- delegate:nil
- resizeDelegate:nil])) {
- callbacks_.reset([[NSMutableArray alloc] init]);
- }
- return self;
-}
-
-- (void)loaded:(BookmarkModel*)model {
- [callbacks_ addObject:[NSNumber numberWithInt:0]];
-}
-
-- (void)beingDeleted:(BookmarkModel*)model {
- [callbacks_ addObject:[NSNumber numberWithInt:1]];
-}
-
-- (void)nodeMoved:(BookmarkModel*)model
- oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
- newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex {
- [callbacks_ addObject:[NSNumber numberWithInt:2]];
-}
-
-- (void)nodeAdded:(BookmarkModel*)model
- parent:(const BookmarkNode*)oldParent index:(int)index {
- [callbacks_ addObject:[NSNumber numberWithInt:3]];
-}
-
-- (void)nodeChanged:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- [callbacks_ addObject:[NSNumber numberWithInt:4]];
-}
-
-- (void)nodeFavIconLoaded:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- [callbacks_ addObject:[NSNumber numberWithInt:5]];
-}
-
-- (void)nodeChildrenReordered:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- [callbacks_ addObject:[NSNumber numberWithInt:6]];
-}
-
-- (void)nodeRemoved:(BookmarkModel*)model
- parent:(const BookmarkNode*)oldParent index:(int)index {
- [callbacks_ addObject:[NSNumber numberWithInt:7]];
-}
-
-// Save the request.
-- (void)openBookmarkURL:(const GURL&)url
- disposition:(WindowOpenDisposition)disposition {
- opens_.push_back(OpenInfo(url, disposition));
-}
-
-@end
-
-
-class BookmarkBarBridgeTest : public CocoaTest {
- public:
- BrowserTestHelper browser_test_helper_;
-};
-
-// Call all the callbacks; make sure they are all redirected to the objc object.
-TEST_F(BookmarkBarBridgeTest, TestRedirect) {
- Browser* browser = browser_test_helper_.browser();
- Profile* profile = browser_test_helper_.profile();
- BookmarkModel* model = profile->GetBookmarkModel();
-
- scoped_nsobject<NSView> parentView([[NSView alloc]
- initWithFrame:NSMakeRect(0,0,100,100)]);
- scoped_nsobject<NSView> webView([[NSView alloc]
- initWithFrame:NSMakeRect(0,0,100,100)]);
- scoped_nsobject<NSView> infoBarsView(
- [[NSView alloc] initWithFrame:NSMakeRect(0,0,100,100)]);
-
- scoped_nsobject<FakeBookmarkBarController>
- controller([[FakeBookmarkBarController alloc] initWithBrowser:browser]);
- EXPECT_TRUE(controller.get());
- scoped_ptr<BookmarkBarBridge> bridge(new BookmarkBarBridge(controller.get(),
- model));
- EXPECT_TRUE(bridge.get());
-
- bridge->Loaded(NULL);
- bridge->BookmarkModelBeingDeleted(NULL);
- bridge->BookmarkNodeMoved(NULL, NULL, 0, NULL, 0);
- bridge->BookmarkNodeAdded(NULL, NULL, 0);
- bridge->BookmarkNodeChanged(NULL, NULL);
- bridge->BookmarkNodeFavIconLoaded(NULL, NULL);
- bridge->BookmarkNodeChildrenReordered(NULL, NULL);
- bridge->BookmarkNodeRemoved(NULL, NULL, 0, NULL);
-
- // 8 calls above plus an initial Loaded() in init routine makes 9
- EXPECT_TRUE([controller.get()->callbacks_ count] == 9);
-
- for (int x = 1; x < 9; x++) {
- NSNumber* num = [NSNumber numberWithInt:x-1];
- EXPECT_NSEQ(num, [controller.get()->callbacks_ objectAtIndex:x]);
- }
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h
deleted file mode 100644
index d1be28f..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2010 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.
-
-// Constants used for positioning the bookmark bar. These aren't placed in a
-// different file because they're conditionally included in cross platform code
-// and thus no Objective-C++ stuff.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_CONSTANTS_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_CONSTANTS_H_
-#pragma once
-
-namespace bookmarks {
-
-// Correction used for computing other values based on the height.
-const int kVisualHeightOffset = 2;
-
-// Bar height, when opened in "always visible" mode. This is actually a little
-// smaller than it should be (by |kVisualHeightOffset| points) because of the
-// visual overlap with the main toolbar. When using this to compute values
-// other than the actual height of the toolbar, be sure to add
-// |kVisualHeightOffset|.
-const int kBookmarkBarHeight = 26;
-
-// Our height, when visible in "new tab page" mode.
-const int kNTPBookmarkBarHeight = 40;
-
-// The amount of space between the inner bookmark bar and the outer toolbar on
-// new tab pages.
-const int kNTPBookmarkBarPadding =
- (kNTPBookmarkBarHeight - (kBookmarkBarHeight + kVisualHeightOffset)) / 2;
-
-// The height of buttons in the bookmark bar.
-const int kBookmarkButtonHeight = kBookmarkBarHeight + kVisualHeightOffset;
-
-} // namespace bookmarks
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_CONSTANTS_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h
deleted file mode 100644
index 6d0a0f6..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-#include <map>
-
-#import "base/chrome_application_mac.h"
-#include "base/scoped_nsobject.h"
-#include "base/scoped_ptr.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_state.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#include "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
-#include "webkit/glue/window_open_disposition.h"
-
-@class BookmarkBarController;
-@class BookmarkBarFolderController;
-@class BookmarkBarView;
-@class BookmarkButton;
-@class BookmarkButtonCell;
-@class BookmarkFolderTarget;
-class BookmarkModel;
-@class BookmarkMenu;
-class BookmarkNode;
-class Browser;
-class GURL;
-class PrefService;
-class TabContents;
-@class ToolbarController;
-@protocol ViewResizer;
-
-namespace bookmarks {
-
-// Magic numbers from Cole
-// TODO(jrg): create an objc-friendly version of bookmark_bar_constants.h?
-
-// Used as a maximum width for buttons on the bar.
-const CGFloat kDefaultBookmarkWidth = 150.0;
-
-// Horizontal frame inset for buttons in the bookmark bar.
-const CGFloat kBookmarkHorizontalPadding = 1.0;
-
-// Vertical frame inset for buttons in the bookmark bar.
-const CGFloat kBookmarkVerticalPadding = 2.0;
-
-// Used as a min/max width for buttons on menus (not on the bar).
-const CGFloat kBookmarkMenuButtonMinimumWidth = 100.0;
-const CGFloat kBookmarkMenuButtonMaximumWidth = 485.0;
-
-// Horizontal separation between a menu button and both edges of its menu.
-const CGFloat kBookmarkSubMenuHorizontalPadding = 5.0;
-
-// TODO(mrossetti): Add constant (kBookmarkVerticalSeparation) for the gap
-// between buttons in a folder menu. Right now we're using
-// kBookmarkVerticalPadding, which is dual purpose and wrong.
-// http://crbug.com/59057
-
-// Convenience constant giving the vertical distance from the top extent of one
-// folder button to the next button.
-const CGFloat kBookmarkButtonVerticalSpan =
- kBookmarkButtonHeight + kBookmarkVerticalPadding;
-
-// The minimum separation between a folder menu and the edge of the screen.
-// If the menu gets closer to the edge of the screen (either right or left)
-// then it is pops up in the opposite direction.
-// (See -[BookmarkBarFolderController childFolderWindowLeftForWidth:]).
-const CGFloat kBookmarkHorizontalScreenPadding = 8.0;
-
-// Our NSScrollView is supposed to be just barely big enough to fit its
-// contentView. It is actually a hair too small.
-// This turns on horizontal scrolling which, although slight, is awkward.
-// Make sure our window (and NSScrollView) are wider than its documentView
-// by at least this much.
-const CGFloat kScrollViewContentWidthMargin = 2;
-
-// Make subfolder menus overlap their parent menu a bit to give a better
-// perception of a menuing system.
-const CGFloat kBookmarkMenuOverlap = 5.0;
-
-// Delay before opening a subfolder (and closing the previous one)
-// when hovering over a folder button.
-const NSTimeInterval kHoverOpenDelay = 0.3;
-
-// Delay on hover before a submenu opens when dragging.
-// Experimentally a drag hover open delay needs to be bigger than a
-// normal (non-drag) menu hover open such as used in the bookmark folder.
-// TODO(jrg): confirm feel of this constant with ui-team.
-// http://crbug.com/36276
-const NSTimeInterval kDragHoverOpenDelay = 0.7;
-
-// Notes on use of kDragHoverCloseDelay in
-// -[BookmarkBarFolderController draggingEntered:].
-//
-// We have an implicit delay on stop-hover-open before a submenu
-// closes. This cannot be zero since it's nice to move the mouse in a
-// direct line from "current position" to "position of item in
-// submenu". However, by doing so, it's possible to overlap a
-// different button on the current menu. Example:
-//
-// Folder1
-// Folder2 ---> Sub1
-// Folder3 Sub2
-// Sub3
-//
-// If you hover over the F in Folder2 to open the sub, and then want to
-// select Sub3, a direct line movement of the mouse may cross over
-// Folder3. Without this delay, that'll cause Sub to be closed before
-// you get there, since a "hover over" of Folder3 gets activated.
-// It's subtle but without the delay it feels broken.
-//
-// This is only really a problem with vertical menu --> vertical menu
-// movement; the bookmark bar (horizontal menu, sort of) seems fine,
-// perhaps because mouse move direction is purely vertical so there is
-// no opportunity for overlap.
-const NSTimeInterval kDragHoverCloseDelay = 0.4;
-
-} // namespace bookmarks
-
-// The interface for the bookmark bar controller's delegate. Currently, the
-// delegate is the BWC and is responsible for ensuring that the toolbar is
-// displayed correctly (as specified by |-getDesiredToolbarHeightCompression|
-// and |-toolbarDividerOpacity|) at the beginning and at the end of an animation
-// (or after a state change).
-@protocol BookmarkBarControllerDelegate
-
-// Sent when the state has changed (after any animation), but before the final
-// display update.
-- (void)bookmarkBar:(BookmarkBarController*)controller
- didChangeFromState:(bookmarks::VisualState)oldState
- toState:(bookmarks::VisualState)newState;
-
-// Sent before the animation begins.
-- (void)bookmarkBar:(BookmarkBarController*)controller
-willAnimateFromState:(bookmarks::VisualState)oldState
- toState:(bookmarks::VisualState)newState;
-
-@end
-
-// A controller for the bookmark bar in the browser window. Handles showing
-// and hiding based on the preference in the given profile.
-@interface BookmarkBarController :
- NSViewController<BookmarkBarState,
- BookmarkBarToolbarViewController,
- BookmarkButtonDelegate,
- BookmarkButtonControllerProtocol,
- CrApplicationEventHookProtocol,
- NSUserInterfaceValidations> {
- @private
- // The visual state of the bookmark bar. If an animation is running, this is
- // set to the "destination" and |lastVisualState_| is set to the "original"
- // state. This is set to |kInvalidState| on initialization (when the
- // appropriate state is not yet known).
- bookmarks::VisualState visualState_;
-
- // The "original" state of the bookmark bar if an animation is running,
- // otherwise it should be |kInvalidState|.
- bookmarks::VisualState lastVisualState_;
-
- Browser* browser_; // weak; owned by its window
- BookmarkModel* bookmarkModel_; // weak; part of the profile owned by the
- // top-level Browser object.
-
- // Our initial view width, which is applied in awakeFromNib.
- CGFloat initialWidth_;
-
- // BookmarkNodes have a 64bit id. NSMenuItems have a 32bit tag used
- // to represent the bookmark node they refer to. This map provides
- // a mapping from one to the other, so we can properly identify the
- // node from the item. When adding items in, we start with seedId_.
- int32 seedId_;
- std::map<int32,int64> menuTagMap_;
-
- // Our bookmark buttons, ordered from L-->R.
- scoped_nsobject<NSMutableArray> buttons_;
-
- // The folder image so we can use one copy for all buttons
- scoped_nsobject<NSImage> folderImage_;
-
- // The default image, so we can use one copy for all buttons.
- scoped_nsobject<NSImage> defaultImage_;
-
- // If the bar is disabled, we hide it and ignore show/hide commands.
- // Set when using fullscreen mode.
- BOOL barIsEnabled_;
-
- // Bridge from Chrome-style C++ notifications (e.g. derived from
- // BookmarkModelObserver)
- scoped_ptr<BookmarkBarBridge> bridge_;
-
- // Delegate that is informed about state changes in the bookmark bar.
- id<BookmarkBarControllerDelegate> delegate_; // weak
-
- // Delegate that can resize us.
- id<ViewResizer> resizeDelegate_; // weak
-
- // Logic for dealing with a click on a bookmark folder button.
- scoped_nsobject<BookmarkFolderTarget> folderTarget_;
-
- // A controller for a pop-up bookmark folder window (custom menu).
- // This is not a scoped_nsobject because it owns itself (when its
- // window closes the controller gets autoreleased).
- BookmarkBarFolderController* folderController_;
-
- // Are watching for a "click outside" or other event which would
- // signal us to close the bookmark bar folder menus?
- BOOL watchingForExitEvent_;
-
- IBOutlet BookmarkBarView* buttonView_; // Contains 'no items' text fields.
- IBOutlet BookmarkButton* offTheSideButton_; // aka the chevron.
- IBOutlet NSMenu* buttonContextMenu_;
-
- NSRect originalNoItemsRect_; // Original, pre-resized field rect.
- NSRect originalImportBookmarksRect_; // Original, pre-resized field rect.
-
- // "Other bookmarks" button on the right side.
- scoped_nsobject<BookmarkButton> otherBookmarksButton_;
-
- // We have a special menu for folder buttons. This starts as a copy
- // of the bar menu.
- scoped_nsobject<BookmarkMenu> buttonFolderContextMenu_;
-
- // When doing a drag, this is folder button "hovered over" which we
- // may want to open after a short delay. There are cases where a
- // mouse-enter can open a folder (e.g. if the menus are "active")
- // but that doesn't use this variable or need a delay so "hover" is
- // the wrong term.
- scoped_nsobject<BookmarkButton> hoverButton_;
-
- // We save the view width when we add bookmark buttons. This lets
- // us avoid a rebuild until we've grown the window bigger than our
- // initial build.
- CGFloat savedFrameWidth_;
-
- // The number of buttons we display in the bookmark bar. This does
- // not include the "off the side" chevron or the "Other Bookmarks"
- // button. We use this number to determine if we need to display
- // the chevron, and to know what to place in the chevron's menu.
- // Since we create everything before doing layout we can't be sure
- // that all bookmark buttons we create will be visible. Thus,
- // [buttons_ count] isn't a definitive check.
- int displayedButtonCount_;
-
- // A state flag which tracks when the bar's folder menus should be shown.
- // An initial click in any of the folder buttons turns this on and
- // one of the following will turn it off: another click in the button,
- // the window losing focus, a click somewhere other than in the bar
- // or a folder menu.
- BOOL showFolderMenus_;
-
- // Set to YES to prevent any node animations. Useful for unit testing so that
- // incomplete animations do not cause valgrind complaints.
- BOOL ignoreAnimations_;
-}
-
-@property(readonly, nonatomic) bookmarks::VisualState visualState;
-@property(readonly, nonatomic) bookmarks::VisualState lastVisualState;
-@property(assign, nonatomic) id<BookmarkBarControllerDelegate> delegate;
-
-// Initializes the bookmark bar controller with the given browser
-// profile and delegates.
-- (id)initWithBrowser:(Browser*)browser
- initialWidth:(CGFloat)initialWidth
- delegate:(id<BookmarkBarControllerDelegate>)delegate
- resizeDelegate:(id<ViewResizer>)resizeDelegate;
-
-// Updates the bookmark bar (from its current, possibly in-transition) state to
-// the one appropriate for the new conditions.
-- (void)updateAndShowNormalBar:(BOOL)showNormalBar
- showDetachedBar:(BOOL)showDetachedBar
- withAnimation:(BOOL)animate;
-
-// Update the visible state of the bookmark bar.
-- (void)updateVisibility;
-
-// Turn on or off the bookmark bar and prevent or reallow its appearance. On
-// disable, toggle off if shown. On enable, show only if needed. App and popup
-// windows do not show a bookmark bar.
-- (void)setBookmarkBarEnabled:(BOOL)enabled;
-
-// Returns the amount by which the toolbar above should be compressed.
-- (CGFloat)getDesiredToolbarHeightCompression;
-
-// Gets the appropriate opacity for the toolbar's divider; 0 means that it
-// shouldn't be shown.
-- (CGFloat)toolbarDividerOpacity;
-
-// Updates the sizes and positions of the subviews.
-// TODO(viettrungluu): I'm not convinced this should be public, but I currently
-// need it for animations. Try not to propagate its use.
-- (void)layoutSubviews;
-
-// Called by our view when it is moved to a window.
-- (void)viewDidMoveToWindow;
-
-// Import bookmarks from another browser.
-- (IBAction)importBookmarks:(id)sender;
-
-// Provide a favIcon for a bookmark node. May return nil.
-- (NSImage*)favIconForNode:(const BookmarkNode*)node;
-
-// Used for situations where the bookmark bar folder menus should no longer
-// be actively popping up. Called when the window loses focus, a click has
-// occured outside the menus or a bookmark has been activated. (Note that this
-// differs from the behavior of the -[BookmarkButtonControllerProtocol
-// closeAllBookmarkFolders] method in that the latter does not terminate menu
-// tracking since it may be being called in response to actions (such as
-// dragging) where a 'stale' menu presentation should first be collapsed before
-// presenting a new menu.)
-- (void)closeFolderAndStopTrackingMenus;
-
-// Checks if operations such as edit or delete are allowed.
-- (BOOL)canEditBookmark:(const BookmarkNode*)node;
-
-// Actions for manipulating bookmarks.
-// Open a normal bookmark or folder from a button, ...
-- (IBAction)openBookmark:(id)sender;
-- (IBAction)openBookmarkFolderFromButton:(id)sender;
-// From the "off the side" button, ...
-- (IBAction)openOffTheSideFolderFromButton:(id)sender;
-// From a context menu over the button, ...
-- (IBAction)openBookmarkInNewForegroundTab:(id)sender;
-- (IBAction)openBookmarkInNewWindow:(id)sender;
-- (IBAction)openBookmarkInIncognitoWindow:(id)sender;
-- (IBAction)editBookmark:(id)sender;
-- (IBAction)cutBookmark:(id)sender;
-- (IBAction)copyBookmark:(id)sender;
-- (IBAction)pasteBookmark:(id)sender;
-- (IBAction)deleteBookmark:(id)sender;
-// From a context menu over the bar, ...
-- (IBAction)openAllBookmarks:(id)sender;
-- (IBAction)openAllBookmarksNewWindow:(id)sender;
-- (IBAction)openAllBookmarksIncognitoWindow:(id)sender;
-// Or from a context menu over either the bar or a button.
-- (IBAction)addPage:(id)sender;
-- (IBAction)addFolder:(id)sender;
-
-@end
-
-// Redirects from BookmarkBarBridge, the C++ object which glues us to
-// the rest of Chromium. Internal to BookmarkBarController.
-@interface BookmarkBarController(BridgeRedirect)
-- (void)loaded:(BookmarkModel*)model;
-- (void)beingDeleted:(BookmarkModel*)model;
-- (void)nodeAdded:(BookmarkModel*)model
- parent:(const BookmarkNode*)oldParent index:(int)index;
-- (void)nodeChanged:(BookmarkModel*)model
- node:(const BookmarkNode*)node;
-- (void)nodeMoved:(BookmarkModel*)model
- oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
- newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex;
-- (void)nodeRemoved:(BookmarkModel*)model
- parent:(const BookmarkNode*)oldParent index:(int)index;
-- (void)nodeFavIconLoaded:(BookmarkModel*)model
- node:(const BookmarkNode*)node;
-- (void)nodeChildrenReordered:(BookmarkModel*)model
- node:(const BookmarkNode*)node;
-@end
-
-// These APIs should only be used by unit tests (or used internally).
-@interface BookmarkBarController(InternalOrTestingAPI)
-- (BookmarkBarView*)buttonView;
-- (NSMutableArray*)buttons;
-- (NSMenu*)offTheSideMenu;
-- (NSButton*)offTheSideButton;
-- (BOOL)offTheSideButtonIsHidden;
-- (BookmarkButton*)otherBookmarksButton;
-- (BookmarkBarFolderController*)folderController;
-- (id)folderTarget;
-- (int)displayedButtonCount;
-- (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition;
-- (void)clearBookmarkBar;
-- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node;
-- (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell xOffset:(int*)xOffset;
-- (void)checkForBookmarkButtonGrowth:(NSButton*)button;
-- (void)frameDidChange;
-- (int64)nodeIdFromMenuTag:(int32)tag;
-- (int32)menuTagFromNodeId:(int64)menuid;
-- (const BookmarkNode*)nodeFromMenuItem:(id)sender;
-- (void)updateTheme:(ThemeProvider*)themeProvider;
-- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point;
-- (BOOL)isEventAnExitEvent:(NSEvent*)event;
-- (BOOL)shrinkOrHideView:(NSView*)view forMaxX:(CGFloat)maxViewX;
-
-// The following are for testing purposes only and are not used internally.
-- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node;
-- (NSMenu*)buttonContextMenu;
-- (void)setButtonContextMenu:(id)menu;
-// Set to YES in order to prevent animations.
-- (void)setIgnoreAnimations:(BOOL)ignore;
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm
deleted file mode 100644
index 3ba0fc9..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm
+++ /dev/null
@@ -1,2497 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-
-#include "app/l10n_util_mac.h"
-#include "app/resource_bundle.h"
-#include "base/mac_util.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_editor.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_utils.h"
-#import "chrome/browser/cocoa/background_gradient_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/event_utils.h"
-#import "chrome/browser/cocoa/fullscreen_controller.h"
-#import "chrome/browser/cocoa/import_settings_dialog.h"
-#import "chrome/browser/cocoa/menu_button.h"
-#import "chrome/browser/cocoa/themed_window.h"
-#import "chrome/browser/cocoa/toolbar_controller.h"
-#import "chrome/browser/cocoa/view_id_util.h"
-#import "chrome/browser/cocoa/view_resizer.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents/tab_contents_view.h"
-#import "chrome/browser/themes/browser_theme_provider.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/common/pref_names.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "skia/ext/skia_utils_mac.h"
-
-// Bookmark bar state changing and animations
-//
-// The bookmark bar has three real states: "showing" (a normal bar attached to
-// the toolbar), "hidden", and "detached" (pretending to be part of the web
-// content on the NTP). It can, or at least should be able to, animate between
-// these states. There are several complications even without animation:
-// - The placement of the bookmark bar is done by the BWC, and it needs to know
-// the state in order to place the bookmark bar correctly (immediately below
-// the toolbar when showing, below the infobar when detached).
-// - The "divider" (a black line) needs to be drawn by either the toolbar (when
-// the bookmark bar is hidden or detached) or by the bookmark bar (when it is
-// showing). It should not be drawn by both.
-// - The toolbar needs to vertically "compress" when the bookmark bar is
-// showing. This ensures the proper display of both the bookmark bar and the
-// toolbar, and gives a padded area around the bookmark bar items for right
-// clicks, etc.
-//
-// Our model is that the BWC controls us and also the toolbar. We try not to
-// talk to the browser nor the toolbar directly, instead centralizing control in
-// the BWC. The key method by which the BWC controls us is
-// |-updateAndShowNormalBar:showDetachedBar:withAnimation:|. This invokes state
-// changes, and at appropriate times we request that the BWC do things for us
-// via either the resize delegate or our general delegate. If the BWC needs any
-// information about what it should do, or tell the toolbar to do, it can then
-// query us back (e.g., |-isShownAs...|, |-getDesiredToolbarHeightCompression|,
-// |-toolbarDividerOpacity|, etc.).
-//
-// Animation-related complications:
-// - Compression of the toolbar is touchy during animation. It must not be
-// compressed while the bookmark bar is animating to/from showing (from/to
-// hidden), otherwise it would look like the bookmark bar's contents are
-// sliding out of the controls inside the toolbar. As such, we have to make
-// sure that the bookmark bar is shown at the right location and at the
-// right height (at various points in time).
-// - Showing the divider is also complicated during animation between hidden
-// and showing. We have to make sure that the toolbar does not show the
-// divider despite the fact that it's not compressed. The exception to this
-// is at the beginning/end of the animation when the toolbar is still
-// uncompressed but the bookmark bar has height 0. If we're not careful, we
-// get a flicker at this point.
-// - We have to ensure that we do the right thing if we're told to change state
-// while we're running an animation. The generic/easy thing to do is to jump
-// to the end state of our current animation, and (if the new state change
-// again involves an animation) begin the new animation. We can do better
-// than that, however, and sometimes just change the current animation to go
-// to the new end state (e.g., by "reversing" the animation in the showing ->
-// hidden -> showing case). We also have to ensure that demands to
-// immediately change state are always honoured.
-//
-// Pointers to animation logic:
-// - |-moveToVisualState:withAnimation:| starts animations, deciding which ones
-// we know how to handle.
-// - |-doBookmarkBarAnimation| has most of the actual logic.
-// - |-getDesiredToolbarHeightCompression| and |-toolbarDividerOpacity| contain
-// related logic.
-// - The BWC's |-layoutSubviews| needs to know how to position things.
-// - The BWC should implement |-bookmarkBar:didChangeFromState:toState:| and
-// |-bookmarkBar:willAnimateFromState:toState:| in order to inform the
-// toolbar of required changes.
-
-namespace {
-
-// Overlap (in pixels) between the toolbar and the bookmark bar (when showing in
-// normal mode).
-const CGFloat kBookmarkBarOverlap = 3.0;
-
-// Duration of the bookmark bar animations.
-const NSTimeInterval kBookmarkBarAnimationDuration = 0.12;
-
-} // namespace
-
-@interface BookmarkBarController(Private)
-
-// Determines the appropriate state for the given situation.
-+ (bookmarks::VisualState)visualStateToShowNormalBar:(BOOL)showNormalBar
- showDetachedBar:(BOOL)showDetachedBar;
-
-// Moves to the given next state (from the current state), possibly animating.
-// If |animate| is NO, it will stop any running animation and jump to the given
-// state. If YES, it may either (depending on implementation) jump to the end of
-// the current animation and begin the next one, or stop the current animation
-// mid-flight and animate to the next state.
-- (void)moveToVisualState:(bookmarks::VisualState)nextVisualState
- withAnimation:(BOOL)animate;
-
-// Return the backdrop to the bookmark bar as various types.
-- (BackgroundGradientView*)backgroundGradientView;
-- (AnimatableView*)animatableView;
-
-// Create buttons for all items in the given bookmark node tree.
-// Modifies self->buttons_. Do not add more buttons than will fit on the view.
-- (void)addNodesToButtonList:(const BookmarkNode*)node;
-
-// Create an autoreleased button appropriate for insertion into the bookmark
-// bar. Update |xOffset| with the offset appropriate for the subsequent button.
-- (BookmarkButton*)buttonForNode:(const BookmarkNode*)node
- xOffset:(int*)xOffset;
-
-// Puts stuff into the final visual state without animating, stopping a running
-// animation if necessary.
-- (void)finalizeVisualState;
-
-// Stops any current animation in its tracks (midway).
-- (void)stopCurrentAnimation;
-
-// Show/hide the bookmark bar.
-// if |animate| is YES, the changes are made using the animator; otherwise they
-// are made immediately.
-- (void)showBookmarkBarWithAnimation:(BOOL)animate;
-
-// Handles animating the resize of the content view. Returns YES if it handled
-// the animation, NO if not (and hence it should be done instantly).
-- (BOOL)doBookmarkBarAnimation;
-
-// |point| is in the base coordinate system of the destination window;
-// it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be
-// made and inserted into the new location while leaving the bookmark in
-// the old location, otherwise move the bookmark by removing from its old
-// location and inserting into the new location.
-- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
- to:(NSPoint)point
- copy:(BOOL)copy;
-
-// Returns the index in the model for a drag to the location given by
-// |point|. This is determined by finding the first button before the center
-// of which |point| falls, scanning left to right. Note that, currently, only
-// the x-coordinate of |point| is considered. Though not currently implemented,
-// we may check for errors, in which case this would return negative value;
-// callers should check for this.
-- (int)indexForDragToPoint:(NSPoint)point;
-
-// Add or remove buttons to/from the bar until it is filled but not overflowed.
-- (void)redistributeButtonsOnBarAsNeeded;
-
-// Determine the nature of the bookmark bar contents based on the number of
-// buttons showing. If too many then show the off-the-side list, if none
-// then show the no items label.
-- (void)reconfigureBookmarkBar;
-
-- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu;
-- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu;
-- (void)tagEmptyMenu:(NSMenu*)menu;
-- (void)clearMenuTagMap;
-- (int)preferredHeight;
-- (void)addNonBookmarkButtonsToView;
-- (void)addButtonsToView;
-- (void)centerNoItemsLabel;
-- (void)setNodeForBarMenu;
-
-- (void)watchForExitEvent:(BOOL)watch;
-
-@end
-
-@implementation BookmarkBarController
-
-@synthesize visualState = visualState_;
-@synthesize lastVisualState = lastVisualState_;
-@synthesize delegate = delegate_;
-
-- (id)initWithBrowser:(Browser*)browser
- initialWidth:(float)initialWidth
- delegate:(id<BookmarkBarControllerDelegate>)delegate
- resizeDelegate:(id<ViewResizer>)resizeDelegate {
- if ((self = [super initWithNibName:@"BookmarkBar"
- bundle:mac_util::MainAppBundle()])) {
- // Initialize to an invalid state.
- visualState_ = bookmarks::kInvalidState;
- lastVisualState_ = bookmarks::kInvalidState;
-
- browser_ = browser;
- initialWidth_ = initialWidth;
- bookmarkModel_ = browser_->profile()->GetBookmarkModel();
- buttons_.reset([[NSMutableArray alloc] init]);
- delegate_ = delegate;
- resizeDelegate_ = resizeDelegate;
- folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- folderImage_.reset(
- [rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]);
- defaultImage_.reset([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON) retain]);
-
- // Register for theme changes, bookmark button pulsing, ...
- NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
- [defaultCenter addObserver:self
- selector:@selector(themeDidChangeNotification:)
- name:kBrowserThemeDidChangeNotification
- object:nil];
- [defaultCenter addObserver:self
- selector:@selector(pulseBookmarkNotification:)
- name:bookmark_button::kPulseBookmarkButtonNotification
- object:nil];
-
- // This call triggers an awakeFromNib, which builds the bar, which
- // might uses folderImage_. So make sure it happens after
- // folderImage_ is loaded.
- [[self animatableView] setResizeDelegate:resizeDelegate];
- }
- return self;
-}
-
-- (void)pulseBookmarkNotification:(NSNotification*)notification {
- NSDictionary* dict = [notification userInfo];
- const BookmarkNode* node = NULL;
- NSValue *value = [dict objectForKey:bookmark_button::kBookmarkKey];
- DCHECK(value);
- if (value)
- node = static_cast<const BookmarkNode*>([value pointerValue]);
- NSNumber* number = [dict
- objectForKey:bookmark_button::kBookmarkPulseFlagKey];
- DCHECK(number);
- BOOL doPulse = number ? [number boolValue] : NO;
-
- // 3 cases:
- // button on the bar: flash it
- // button in "other bookmarks" folder: flash other bookmarks
- // button in "off the side" folder: flash the chevron
- for (BookmarkButton* button in [self buttons]) {
- if ([button bookmarkNode] == node) {
- [button setIsContinuousPulsing:doPulse];
- return;
- }
- }
- if ([otherBookmarksButton_ bookmarkNode] == node) {
- [otherBookmarksButton_ setIsContinuousPulsing:doPulse];
- return;
- }
- if (node->GetParent() == bookmarkModel_->GetBookmarkBarNode()) {
- [offTheSideButton_ setIsContinuousPulsing:doPulse];
- return;
- }
-
- NOTREACHED() << "no bookmark button found to pulse!";
-}
-
-- (void)dealloc {
- // We better stop any in-flight animation if we're being killed.
- [[self animatableView] stopAnimation];
-
- // Remove our view from its superview so it doesn't attempt to reference
- // it when the controller is gone.
- //TODO(dmaclach): Remove -- http://crbug.com/25845
- [[self view] removeFromSuperview];
-
- // Be sure there is no dangling pointer.
- if ([[self view] respondsToSelector:@selector(setController:)])
- [[self view] performSelector:@selector(setController:) withObject:nil];
-
- // For safety, make sure the buttons can no longer call us.
- for (BookmarkButton* button in buttons_.get()) {
- [button setDelegate:nil];
- [button setTarget:nil];
- [button setAction:nil];
- }
-
- bridge_.reset(NULL);
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [self watchForExitEvent:NO];
- [super dealloc];
-}
-
-- (void)awakeFromNib {
- // We default to NOT open, which means height=0.
- DCHECK([[self view] isHidden]); // Hidden so it's OK to change.
-
- // Set our initial height to zero, since that is what the superview
- // expects. We will resize ourselves open later if needed.
- [[self view] setFrame:NSMakeRect(0, 0, initialWidth_, 0)];
-
- // Complete init of the "off the side" button, as much as we can.
- [offTheSideButton_ setDraggable:NO];
-
- // We are enabled by default.
- barIsEnabled_ = YES;
-
- // Remember the original sizes of the 'no items' and 'import bookmarks'
- // fields to aid in resizing when the window frame changes.
- originalNoItemsRect_ = [[buttonView_ noItemTextfield] frame];
- originalImportBookmarksRect_ = [[buttonView_ importBookmarksButton] frame];
-
- // To make life happier when the bookmark bar is floating, the chevron is a
- // child of the button view.
- [offTheSideButton_ removeFromSuperview];
- [buttonView_ addSubview:offTheSideButton_];
-
- // Copy the bar menu so we know if it's from the bar or a folder.
- // Then we set its represented item to be the bookmark bar.
- buttonFolderContextMenu_.reset([[[self view] menu] copy]);
-
- // When resized we may need to add new buttons, or remove them (if
- // no longer visible), or add/remove the "off the side" menu.
- [[self view] setPostsFrameChangedNotifications:YES];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(frameDidChange)
- name:NSViewFrameDidChangeNotification
- object:[self view]];
-
- // Watch for things going to or from fullscreen.
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(willEnterOrLeaveFullscreen:)
- name:kWillEnterFullscreenNotification
- object:nil];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(willEnterOrLeaveFullscreen:)
- name:kWillLeaveFullscreenNotification
- object:nil];
-
- // Don't pass ourself along (as 'self') until our init is completely
- // done. Thus, this call is (almost) last.
- bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_));
-}
-
-// Called by our main view (a BookmarkBarView) when it gets moved to a
-// window. We perform operations which need to know the relevant
-// window (e.g. watch for a window close) so they can't be performed
-// earlier (such as in awakeFromNib).
-- (void)viewDidMoveToWindow {
- NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
-
- // Remove any existing notifications before registering for new ones.
- [defaultCenter removeObserver:self
- name:NSWindowWillCloseNotification
- object:nil];
- [defaultCenter removeObserver:self
- name:NSWindowDidResignKeyNotification
- object:nil];
-
- [defaultCenter addObserver:self
- selector:@selector(parentWindowWillClose:)
- name:NSWindowWillCloseNotification
- object:[[self view] window]];
- [defaultCenter addObserver:self
- selector:@selector(parentWindowDidResignKey:)
- name:NSWindowDidResignKeyNotification
- object:[[self view] window]];
-}
-
-// When going fullscreen we can run into trouble. Our view is removed
-// from the non-fullscreen window before the non-fullscreen window
-// loses key, so our parentDidResignKey: callback never gets called.
-// In addition, a bookmark folder controller needs to be autoreleased
-// (in case it's in the event chain when closed), but the release
-// implicitly needs to happen while it's connected to the original
-// (non-fullscreen) window to "unlock bar visibility". Such a
-// contract isn't honored when going fullscreen with the menu option
-// (not with the keyboard shortcut). We fake it as best we can here.
-// We have a similar problem leaving fullscreen.
-- (void)willEnterOrLeaveFullscreen:(NSNotification*)notification {
- if (folderController_) {
- [self childFolderWillClose:folderController_];
- [self closeFolderAndStopTrackingMenus];
- }
-}
-
-// NSNotificationCenter callback.
-- (void)parentWindowWillClose:(NSNotification*)notification {
- [self closeFolderAndStopTrackingMenus];
-}
-
-// NSNotificationCenter callback.
-- (void)parentWindowDidResignKey:(NSNotification*)notification {
- [self closeFolderAndStopTrackingMenus];
-}
-
-// Change the layout of the bookmark bar's subviews in response to a visibility
-// change (e.g., show or hide the bar) or style change (attached or floating).
-- (void)layoutSubviews {
- NSRect frame = [[self view] frame];
- NSRect buttonViewFrame = NSMakeRect(0, 0, NSWidth(frame), NSHeight(frame));
-
- // The state of our morph (if any); 1 is total bubble, 0 is the regular bar.
- CGFloat morph = [self detachedMorphProgress];
-
- // Add padding to the detached bookmark bar.
- buttonViewFrame = NSInsetRect(buttonViewFrame,
- morph * bookmarks::kNTPBookmarkBarPadding,
- morph * bookmarks::kNTPBookmarkBarPadding);
-
- [buttonView_ setFrame:buttonViewFrame];
-}
-
-// We don't change a preference; we only change visibility. Preference changing
-// (global state) is handled in |BrowserWindowCocoa::ToggleBookmarkBar()|. We
-// simply update based on what we're told.
-- (void)updateVisibility {
- [self showBookmarkBarWithAnimation:NO];
-}
-
-- (void)setBookmarkBarEnabled:(BOOL)enabled {
- if (enabled != barIsEnabled_) {
- barIsEnabled_ = enabled;
- [self updateVisibility];
- }
-}
-
-- (CGFloat)getDesiredToolbarHeightCompression {
- // Some special cases....
- if (!barIsEnabled_)
- return 0;
-
- if ([self isAnimationRunning]) {
- // No toolbar compression when animating between hidden and showing, nor
- // between showing and detached.
- if ([self isAnimatingBetweenState:bookmarks::kHiddenState
- andState:bookmarks::kShowingState] ||
- [self isAnimatingBetweenState:bookmarks::kShowingState
- andState:bookmarks::kDetachedState])
- return 0;
-
- // If we ever need any other animation cases, code would go here.
- }
-
- return [self isInState:bookmarks::kShowingState] ? kBookmarkBarOverlap : 0;
-}
-
-- (CGFloat)toolbarDividerOpacity {
- // Some special cases....
- if ([self isAnimationRunning]) {
- // In general, the toolbar shouldn't show a divider while we're animating
- // between showing and hidden. The exception is when our height is < 1, in
- // which case we can't draw it. It's all-or-nothing (no partial opacity).
- if ([self isAnimatingBetweenState:bookmarks::kHiddenState
- andState:bookmarks::kShowingState])
- return (NSHeight([[self view] frame]) < 1) ? 1 : 0;
-
- // The toolbar should show the divider when animating between showing and
- // detached (but opacity will vary).
- if ([self isAnimatingBetweenState:bookmarks::kShowingState
- andState:bookmarks::kDetachedState])
- return static_cast<CGFloat>([self detachedMorphProgress]);
-
- // If we ever need any other animation cases, code would go here.
- }
-
- // In general, only show the divider when it's in the normal showing state.
- return [self isInState:bookmarks::kShowingState] ? 0 : 1;
-}
-
-- (NSImage*)favIconForNode:(const BookmarkNode*)node {
- if (!node)
- return defaultImage_;
-
- if (node->is_folder())
- return folderImage_;
-
- const SkBitmap& favIcon = bookmarkModel_->GetFavIcon(node);
- if (!favIcon.isNull())
- return gfx::SkBitmapToNSImage(favIcon);
-
- return defaultImage_;
-}
-
-- (void)closeFolderAndStopTrackingMenus {
- showFolderMenus_ = NO;
- [self closeAllBookmarkFolders];
-}
-
-- (BOOL)canEditBookmark:(const BookmarkNode*)node {
- // Don't allow edit/delete of the bar node, or of "Other Bookmarks"
- if ((node == nil) ||
- (node == bookmarkModel_->other_node()) ||
- (node == bookmarkModel_->GetBookmarkBarNode()))
- return NO;
- return YES;
-}
-
-#pragma mark Actions
-
-- (IBAction)openBookmark:(id)sender {
- [self closeFolderAndStopTrackingMenus];
- DCHECK([sender respondsToSelector:@selector(bookmarkNode)]);
- const BookmarkNode* node = [sender bookmarkNode];
- WindowOpenDisposition disposition =
- event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
- [self openURL:node->GetURL() disposition:disposition];
-}
-
-// Redirect to our logic shared with BookmarkBarFolderController.
-- (IBAction)openBookmarkFolderFromButton:(id)sender {
- if (sender != offTheSideButton_) {
- // Toggle presentation of bar folder menus.
- showFolderMenus_ = !showFolderMenus_;
- [folderTarget_ openBookmarkFolderFromButton:sender];
- } else {
- // Off-the-side requires special handling.
- [self openOffTheSideFolderFromButton:sender];
- }
-}
-
-// The button that sends this one is special; the "off the side"
-// button (chevron) opens like a folder button but isn't exactly a
-// parent folder.
-- (IBAction)openOffTheSideFolderFromButton:(id)sender {
- DCHECK([sender isKindOfClass:[BookmarkButton class]]);
- DCHECK([[sender cell] isKindOfClass:[BookmarkButtonCell class]]);
- [[sender cell] setStartingChildIndex:displayedButtonCount_];
- [folderTarget_ openBookmarkFolderFromButton:sender];
-}
-
-- (IBAction)openBookmarkInNewForegroundTab:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node)
- [self openURL:node->GetURL() disposition:NEW_FOREGROUND_TAB];
- [self closeAllBookmarkFolders];
-}
-
-- (IBAction)openBookmarkInNewWindow:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node)
- [self openURL:node->GetURL() disposition:NEW_WINDOW];
-}
-
-- (IBAction)openBookmarkInIncognitoWindow:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node)
- [self openURL:node->GetURL() disposition:OFF_THE_RECORD];
-}
-
-- (IBAction)editBookmark:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (!node)
- return;
-
- if (node->is_folder()) {
- BookmarkNameFolderController* controller =
- [[BookmarkNameFolderController alloc]
- initWithParentWindow:[[self view] window]
- profile:browser_->profile()
- node:node];
- [controller runAsModalSheet];
- return;
- }
-
- // There is no real need to jump to a platform-common routine at
- // this point (which just jumps back to objc) other than consistency
- // across platforms.
- //
- // TODO(jrg): identify when we NO_TREE. I can see it in the code
- // for the other platforms but can't find a way to trigger it in the
- // UI.
- BookmarkEditor::Show([[self view] window],
- browser_->profile(),
- node->GetParent(),
- BookmarkEditor::EditDetails(node),
- BookmarkEditor::SHOW_TREE);
-}
-
-- (IBAction)cutBookmark:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- std::vector<const BookmarkNode*> nodes;
- nodes.push_back(node);
- bookmark_utils::CopyToClipboard(bookmarkModel_, nodes, true);
- }
-}
-
-- (IBAction)copyBookmark:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- std::vector<const BookmarkNode*> nodes;
- nodes.push_back(node);
- bookmark_utils::CopyToClipboard(bookmarkModel_, nodes, false);
- }
-}
-
-// Paste the copied node immediately after the node for which the context
-// menu has been presented if the node is a non-folder bookmark, otherwise
-// past at the end of the folder node.
-- (IBAction)pasteBookmark:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- int index = -1;
- if (node != bookmarkModel_->GetBookmarkBarNode() && !node->is_folder()) {
- const BookmarkNode* parent = node->GetParent();
- index = parent->IndexOfChild(node) + 1;
- if (index > parent->GetChildCount())
- index = -1;
- node = parent;
- }
- bookmark_utils::PasteFromClipboard(bookmarkModel_, node, index);
- }
-}
-
-- (IBAction)deleteBookmark:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- bookmarkModel_->Remove(node->GetParent(),
- node->GetParent()->IndexOfChild(node));
- }
-}
-
-- (IBAction)openAllBookmarks:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- [self openAll:node disposition:NEW_FOREGROUND_TAB];
- UserMetrics::RecordAction(UserMetricsAction("OpenAllBookmarks"),
- browser_->profile());
- }
-}
-
-- (IBAction)openAllBookmarksNewWindow:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- [self openAll:node disposition:NEW_WINDOW];
- UserMetrics::RecordAction(UserMetricsAction("OpenAllBookmarksNewWindow"),
- browser_->profile());
- }
-}
-
-- (IBAction)openAllBookmarksIncognitoWindow:(id)sender {
- const BookmarkNode* node = [self nodeFromMenuItem:sender];
- if (node) {
- [self openAll:node disposition:OFF_THE_RECORD];
- UserMetrics::RecordAction(
- UserMetricsAction("OpenAllBookmarksIncognitoWindow"),
- browser_->profile());
- }
-}
-
-// May be called from the bar or from a folder button.
-// If called from a button, that button becomes the parent.
-- (IBAction)addPage:(id)sender {
- const BookmarkNode* parent = [self nodeFromMenuItem:sender];
- if (!parent)
- parent = bookmarkModel_->GetBookmarkBarNode();
- BookmarkEditor::Show([[self view] window],
- browser_->profile(),
- parent,
- BookmarkEditor::EditDetails(),
- BookmarkEditor::SHOW_TREE);
-}
-
-// Might be called from the context menu over the bar OR over a
-// button. If called from a button, that button becomes a sibling of
-// the new node. If called from the bar, add to the end of the bar.
-- (IBAction)addFolder:(id)sender {
- const BookmarkNode* senderNode = [self nodeFromMenuItem:sender];
- const BookmarkNode* parent = NULL;
- int newIndex = 0;
- // If triggered from the bar, folder or "others" folder - add as a child to
- // the end.
- // If triggered from a bookmark, add as next sibling.
- BookmarkNode::Type type = senderNode->type();
- if (type == BookmarkNode::BOOKMARK_BAR ||
- type == BookmarkNode::OTHER_NODE ||
- type == BookmarkNode::FOLDER) {
- parent = senderNode;
- newIndex = parent->GetChildCount();
- } else {
- parent = senderNode->GetParent();
- newIndex = parent->IndexOfChild(senderNode) + 1;
- }
- BookmarkNameFolderController* controller =
- [[BookmarkNameFolderController alloc]
- initWithParentWindow:[[self view] window]
- profile:browser_->profile()
- parent:parent
- newIndex:newIndex];
- [controller runAsModalSheet];
-}
-
-- (IBAction)importBookmarks:(id)sender {
- [ImportSettingsDialogController showImportSettingsDialogForProfile:
- browser_->profile()];
-}
-
-#pragma mark Private Methods
-
-// Called after the current theme has changed.
-- (void)themeDidChangeNotification:(NSNotification*)aNotification {
- ThemeProvider* themeProvider =
- static_cast<ThemeProvider*>([[aNotification object] pointerValue]);
- [self updateTheme:themeProvider];
-}
-
-// (Private) Method is the same as [self view], but is provided to be explicit.
-- (BackgroundGradientView*)backgroundGradientView {
- DCHECK([[self view] isKindOfClass:[BackgroundGradientView class]]);
- return (BackgroundGradientView*)[self view];
-}
-
-// (Private) Method is the same as [self view], but is provided to be explicit.
-- (AnimatableView*)animatableView {
- DCHECK([[self view] isKindOfClass:[AnimatableView class]]);
- return (AnimatableView*)[self view];
-}
-
-// Position the off-the-side chevron to the left of the otherBookmarks button.
-- (void)positionOffTheSideButton {
- NSRect frame = [offTheSideButton_ frame];
- if (otherBookmarksButton_.get()) {
- frame.origin.x = ([otherBookmarksButton_ frame].origin.x -
- (frame.size.width +
- bookmarks::kBookmarkHorizontalPadding));
- [offTheSideButton_ setFrame:frame];
- }
-}
-
-// Configure the off-the-side button (e.g. specify the node range,
-// check if we should enable or disable it, etc).
-- (void)configureOffTheSideButtonContentsAndVisibility {
- // If deleting a button while off-the-side is open, buttons may be
- // promoted from off-the-side to the bar. Accomodate.
- if (folderController_ &&
- ([folderController_ parentButton] == offTheSideButton_)) {
- [folderController_ reconfigureMenu];
- }
-
- [[offTheSideButton_ cell] setStartingChildIndex:displayedButtonCount_];
- [[offTheSideButton_ cell]
- setBookmarkNode:bookmarkModel_->GetBookmarkBarNode()];
- int bookmarkChildren = bookmarkModel_->GetBookmarkBarNode()->GetChildCount();
- if (bookmarkChildren > displayedButtonCount_) {
- [offTheSideButton_ setHidden:NO];
- } else {
- // If we just deleted the last item in an off-the-side menu so the
- // button will be going away, make sure the menu goes away.
- if (folderController_ &&
- ([folderController_ parentButton] == offTheSideButton_))
- [self closeAllBookmarkFolders];
- // (And hide the button, too.)
- [offTheSideButton_ setHidden:YES];
- }
-}
-
-// Begin (or end) watching for a click outside this window. Unlike
-// normal NSWindows, bookmark folder "fake menu" windows do not become
-// key or main. Thus, traditional notification (e.g. WillResignKey)
-// won't work. Our strategy is to watch (at the app level) for a
-// "click outside" these windows to detect when they logically lose
-// focus.
-- (void)watchForExitEvent:(BOOL)watch {
- CrApplication* app = static_cast<CrApplication*>([NSApplication
- sharedApplication]);
- DCHECK([app isKindOfClass:[CrApplication class]]);
- if (watch) {
- if (!watchingForExitEvent_)
- [app addEventHook:self];
- } else {
- if (watchingForExitEvent_)
- [app removeEventHook:self];
- }
- watchingForExitEvent_ = watch;
-}
-
-// Keep the "no items" label centered in response to a frame size change.
-- (void)centerNoItemsLabel {
- // Note that this computation is done in the parent's coordinate system,
- // which is unflipped. Also, we want the label to be a fixed distance from
- // the bottom, so that it slides up properly (on animating to hidden).
- // The textfield sits in the itemcontainer, so to center it we maintain
- // equal vertical padding on the top and bottom.
- int yoffset = (NSHeight([[buttonView_ noItemTextfield] frame]) -
- NSHeight([[buttonView_ noItemContainer] frame])) / 2;
- [[buttonView_ noItemContainer] setFrameOrigin:NSMakePoint(0, yoffset)];
-}
-
-// (Private)
-- (void)showBookmarkBarWithAnimation:(BOOL)animate {
- if (animate && !ignoreAnimations_) {
- // If |-doBookmarkBarAnimation| does the animation, we're done.
- if ([self doBookmarkBarAnimation])
- return;
-
- // Else fall through and do the change instantly.
- }
-
- // Set our height.
- [resizeDelegate_ resizeView:[self view]
- newHeight:[self preferredHeight]];
-
- // Only show the divider if showing the normal bookmark bar.
- BOOL showsDivider = [self isInState:bookmarks::kShowingState];
- [[self backgroundGradientView] setShowsDivider:showsDivider];
-
- // Make sure we're shown.
- [[self view] setHidden:![self isVisible]];
-
- // Update everything else.
- [self layoutSubviews];
- [self frameDidChange];
-}
-
-// (Private)
-- (BOOL)doBookmarkBarAnimation {
- if ([self isAnimatingFromState:bookmarks::kHiddenState
- toState:bookmarks::kShowingState]) {
- [[self backgroundGradientView] setShowsDivider:YES];
- [[self view] setHidden:NO];
- AnimatableView* view = [self animatableView];
- // Height takes into account the extra height we have since the toolbar
- // only compresses when we're done.
- [view animateToNewHeight:(bookmarks::kBookmarkBarHeight -
- kBookmarkBarOverlap)
- duration:kBookmarkBarAnimationDuration];
- } else if ([self isAnimatingFromState:bookmarks::kShowingState
- toState:bookmarks::kHiddenState]) {
- [[self backgroundGradientView] setShowsDivider:YES];
- [[self view] setHidden:NO];
- AnimatableView* view = [self animatableView];
- [view animateToNewHeight:0
- duration:kBookmarkBarAnimationDuration];
- } else if ([self isAnimatingFromState:bookmarks::kShowingState
- toState:bookmarks::kDetachedState]) {
- [[self backgroundGradientView] setShowsDivider:YES];
- [[self view] setHidden:NO];
- AnimatableView* view = [self animatableView];
- [view animateToNewHeight:bookmarks::kNTPBookmarkBarHeight
- duration:kBookmarkBarAnimationDuration];
- } else if ([self isAnimatingFromState:bookmarks::kDetachedState
- toState:bookmarks::kShowingState]) {
- [[self backgroundGradientView] setShowsDivider:YES];
- [[self view] setHidden:NO];
- AnimatableView* view = [self animatableView];
- // Height takes into account the extra height we have since the toolbar
- // only compresses when we're done.
- [view animateToNewHeight:(bookmarks::kBookmarkBarHeight -
- kBookmarkBarOverlap)
- duration:kBookmarkBarAnimationDuration];
- } else {
- // Oops! An animation we don't know how to handle.
- return NO;
- }
-
- return YES;
-}
-
-// Enable or disable items. We are the menu delegate for both the bar
-// and for bookmark folder buttons.
-- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem {
- // NSUserInterfaceValidations says that the passed-in object has type
- // |id<NSValidatedUserInterfaceItem>|, but this function needs to call the
- // NSObject method -isKindOfClass: on the parameter. In theory, this is not
- // correct, but this is probably a bug in the method signature.
- NSMenuItem* item = static_cast<NSMenuItem*>(anItem);
- // Yes for everything we don't explicitly deny.
- if (![item isKindOfClass:[NSMenuItem class]])
- return YES;
-
- // Yes if we're not a special BookmarkMenu.
- if (![[item menu] isKindOfClass:[BookmarkMenu class]])
- return YES;
-
- // No if we think it's a special BookmarkMenu but have trouble.
- const BookmarkNode* node = [self nodeFromMenuItem:item];
- if (!node)
- return NO;
-
- // If this is the bar menu, we only have things to do if there are
- // buttons. If this is a folder button menu, we only have things to
- // do if the folder has items.
- NSMenu* menu = [item menu];
- BOOL thingsToDo = NO;
- if (menu == [[self view] menu]) {
- thingsToDo = [buttons_ count] ? YES : NO;
- } else {
- if (node && node->is_folder() && node->GetChildCount()) {
- thingsToDo = YES;
- }
- }
-
- // Disable openAll* if we have nothing to do.
- SEL action = [item action];
- if ((!thingsToDo) &&
- ((action == @selector(openAllBookmarks:)) ||
- (action == @selector(openAllBookmarksNewWindow:)) ||
- (action == @selector(openAllBookmarksIncognitoWindow:)))) {
- return NO;
- }
-
- if ((action == @selector(editBookmark:)) ||
- (action == @selector(deleteBookmark:)) ||
- (action == @selector(cutBookmark:)) ||
- (action == @selector(copyBookmark:))) {
- if (![self canEditBookmark:node]) {
- return NO;
- }
- }
-
- if (action == @selector(pasteBookmark:) &&
- !bookmark_utils::CanPasteFromClipboard(node))
- return NO;
-
- // If this is an incognito window, don't allow "open in incognito".
- if ((action == @selector(openBookmarkInIncognitoWindow:)) ||
- (action == @selector(openAllBookmarksIncognitoWindow:))) {
- if (browser_->profile()->IsOffTheRecord()) {
- return NO;
- }
- }
-
- // Enabled by default.
- return YES;
-}
-
-// Actually open the URL. This is the last chance for a unit test to
-// override.
-- (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition {
- browser_->OpenURL(url, GURL(), disposition, PageTransition::AUTO_BOOKMARK);
-}
-
-- (void)clearMenuTagMap {
- seedId_ = 0;
- menuTagMap_.clear();
-}
-
-- (int)preferredHeight {
- DCHECK(![self isAnimationRunning]);
-
- if (!barIsEnabled_)
- return 0;
-
- switch (visualState_) {
- case bookmarks::kShowingState:
- return bookmarks::kBookmarkBarHeight;
- case bookmarks::kDetachedState:
- return bookmarks::kNTPBookmarkBarHeight;
- case bookmarks::kHiddenState:
- return 0;
- case bookmarks::kInvalidState:
- default:
- NOTREACHED();
- return 0;
- }
-}
-
-// Recursively add the given bookmark node and all its children to
-// menu, one menu item per node.
-- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu {
- NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child];
- NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title
- action:nil
- keyEquivalent:@""] autorelease];
- [menu addItem:item];
- [item setImage:[self favIconForNode:child]];
- if (child->is_folder()) {
- NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease];
- [menu setSubmenu:submenu forItem:item];
- if (child->GetChildCount()) {
- [self addFolderNode:child toMenu:submenu]; // potentially recursive
- } else {
- [self tagEmptyMenu:submenu];
- }
- } else {
- [item setTarget:self];
- [item setAction:@selector(openBookmarkMenuItem:)];
- [item setTag:[self menuTagFromNodeId:child->id()]];
- // Add a tooltip
- std::string url_string = child->GetURL().possibly_invalid_spec();
- NSString* tooltip = [NSString stringWithFormat:@"%@\n%s",
- base::SysUTF16ToNSString(child->GetTitle()),
- url_string.c_str()];
- [item setToolTip:tooltip];
- }
-}
-
-// Empty menus are odd; if empty, add something to look at.
-// Matches windows behavior.
-- (void)tagEmptyMenu:(NSMenu*)menu {
- NSString* empty_menu_title = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU);
- [menu addItem:[[[NSMenuItem alloc] initWithTitle:empty_menu_title
- action:NULL
- keyEquivalent:@""] autorelease]];
-}
-
-// Add the children of the given bookmark node (and their children...)
-// to menu, one menu item per node.
-- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu {
- for (int i = 0; i < node->GetChildCount(); i++) {
- const BookmarkNode* child = node->GetChild(i);
- [self addNode:child toMenu:menu];
- }
-}
-
-// Return an autoreleased NSMenu that represents the given bookmark
-// folder node.
-- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node {
- if (!node->is_folder())
- return nil;
- NSString* title = base::SysUTF16ToNSString(node->GetTitle());
- NSMenu* menu = [[[NSMenu alloc] initWithTitle:title] autorelease];
- [self addFolderNode:node toMenu:menu];
-
- if (![menu numberOfItems]) {
- [self tagEmptyMenu:menu];
- }
- return menu;
-}
-
-// Return an appropriate width for the given bookmark button cell.
-// The "+2" is needed because, sometimes, Cocoa is off by a tad.
-// Example: for a bookmark named "Moma" or "SFGate", it is one pixel
-// too small. For "FBL" it is 2 pixels too small.
-// For a bookmark named "SFGateFooWoo", it is just fine.
-- (CGFloat)widthForBookmarkButtonCell:(NSCell*)cell {
- CGFloat desired = [cell cellSize].width + 2;
- return std::min(desired, bookmarks::kDefaultBookmarkWidth);
-}
-
-- (IBAction)openBookmarkMenuItem:(id)sender {
- int64 tag = [self nodeIdFromMenuTag:[sender tag]];
- const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag);
- WindowOpenDisposition disposition =
- event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
- [self openURL:node->GetURL() disposition:disposition];
-}
-
-// For the given root node of the bookmark bar, show or hide (as
-// appropriate) the "no items" container (text which says "bookmarks
-// go here").
-- (void)showOrHideNoItemContainerForNode:(const BookmarkNode*)node {
- BOOL hideNoItemWarning = node->GetChildCount() > 0;
- [[buttonView_ noItemContainer] setHidden:hideNoItemWarning];
-}
-
-// TODO(jrg): write a "build bar" so there is a nice spot for things
-// like the contextual menu which is invoked when not over a
-// bookmark. On Safari that menu has a "new folder" option.
-- (void)addNodesToButtonList:(const BookmarkNode*)node {
- [self showOrHideNoItemContainerForNode:node];
-
- CGFloat maxViewX = NSMaxX([[self view] bounds]);
- int xOffset = 0;
- for (int i = 0; i < node->GetChildCount(); i++) {
- const BookmarkNode* child = node->GetChild(i);
- BookmarkButton* button = [self buttonForNode:child xOffset:&xOffset];
- if (NSMinX([button frame]) >= maxViewX)
- break;
- [buttons_ addObject:button];
- }
-}
-
-- (BookmarkButton*)buttonForNode:(const BookmarkNode*)node
- xOffset:(int*)xOffset {
- BookmarkButtonCell* cell = [self cellForBookmarkNode:node];
- NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:xOffset];
-
- scoped_nsobject<BookmarkButton>
- button([[BookmarkButton alloc] initWithFrame:frame]);
- DCHECK(button.get());
-
- // [NSButton setCell:] warns to NOT use setCell: other than in the
- // initializer of a control. However, we are using a basic
- // NSButton whose initializer does not take an NSCell as an
- // object. To honor the assumed semantics, we do nothing with
- // NSButton between alloc/init and setCell:.
- [button setCell:cell];
- [button setDelegate:self];
-
- // We cannot set the button cell's text color until it is placed in
- // the button (e.g. the [button setCell:cell] call right above). We
- // also cannot set the cell's text color until the view is added to
- // the hierarchy. If that second part is now true, set the color.
- // (If not we'll set the color on the 1st themeChanged:
- // notification.)
- ThemeProvider* themeProvider = [[[self view] window] themeProvider];
- if (themeProvider) {
- NSColor* color =
- themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT,
- true);
- [cell setTextColor:color];
- }
-
- if (node->is_folder()) {
- [button setTarget:self];
- [button setAction:@selector(openBookmarkFolderFromButton:)];
- } else {
- // Make the button do something
- [button setTarget:self];
- [button setAction:@selector(openBookmark:)];
- // Add a tooltip.
- NSString* title = base::SysUTF16ToNSString(node->GetTitle());
- std::string url_string = node->GetURL().possibly_invalid_spec();
- NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title,
- url_string.c_str()];
- [button setToolTip:tooltip];
- }
- return [[button.get() retain] autorelease];
-}
-
-// Add non-bookmark buttons to the view. This includes the chevron
-// and the "other bookmarks" button. Technically "other bookmarks" is
-// a bookmark button but it is treated specially. Only needs to be
-// called when these buttons are new or when the bookmark bar is
-// cleared (e.g. on a loaded: call). Unlike addButtonsToView below,
-// we don't need to add/remove these dynamically in response to window
-// resize.
-- (void)addNonBookmarkButtonsToView {
- [buttonView_ addSubview:otherBookmarksButton_.get()];
- [buttonView_ addSubview:offTheSideButton_];
-}
-
-// Add bookmark buttons to the view only if they are completely
-// visible and don't overlap the "other bookmarks". Remove buttons
-// which are clipped. Called when building the bookmark bar the first time.
-- (void)addButtonsToView {
- displayedButtonCount_ = 0;
- NSMutableArray* buttons = [self buttons];
- for (NSButton* button in buttons) {
- if (NSMaxX([button frame]) > (NSMinX([offTheSideButton_ frame]) -
- bookmarks::kBookmarkHorizontalPadding))
- break;
- [buttonView_ addSubview:button];
- ++displayedButtonCount_;
- }
- NSUInteger removalCount =
- [buttons count] - (NSUInteger)displayedButtonCount_;
- if (removalCount > 0) {
- NSRange removalRange = NSMakeRange(displayedButtonCount_, removalCount);
- [buttons removeObjectsInRange:removalRange];
- }
-}
-
-// Create the button for "Other Bookmarks" on the right of the bar.
-- (void)createOtherBookmarksButton {
- // Can't create this until the model is loaded, but only need to
- // create it once.
- if (otherBookmarksButton_.get())
- return;
-
- // TODO(jrg): remove duplicate code
- NSCell* cell = [self cellForBookmarkNode:bookmarkModel_->other_node()];
- int ignored = 0;
- NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:&ignored];
- frame.origin.x = [[self buttonView] bounds].size.width - frame.size.width;
- frame.origin.x -= bookmarks::kBookmarkHorizontalPadding;
- BookmarkButton* button = [[BookmarkButton alloc] initWithFrame:frame];
- [button setDraggable:NO];
- otherBookmarksButton_.reset(button);
- view_id_util::SetID(button, VIEW_ID_OTHER_BOOKMARKS);
-
- // Make sure this button, like all other BookmarkButtons, lives
- // until the end of the current event loop.
- [[button retain] autorelease];
-
- // Peg at right; keep same height as bar.
- [button setAutoresizingMask:(NSViewMinXMargin)];
- [button setCell:cell];
- [button setDelegate:self];
- [button setTarget:self];
- [button setAction:@selector(openBookmarkFolderFromButton:)];
- [buttonView_ addSubview:button];
-
- // Now that it's here, move the chevron over.
- [self positionOffTheSideButton];
-}
-
-// Now that the model is loaded, set the bookmark bar root as the node
-// represented by the bookmark bar (default, background) menu.
-- (void)setNodeForBarMenu {
- const BookmarkNode* node = bookmarkModel_->GetBookmarkBarNode();
- BookmarkMenu* menu = static_cast<BookmarkMenu*>([[self view] menu]);
-
- // Make sure types are compatible
- DCHECK(sizeof(long long) == sizeof(int64));
- [menu setRepresentedObject:[NSNumber numberWithLongLong:node->id()]];
-}
-
-// To avoid problems with sync, changes that may impact the current
-// bookmark (e.g. deletion) make sure context menus are closed. This
-// prevents deleting a node which no longer exists.
-- (void)cancelMenuTracking {
- [buttonContextMenu_ cancelTracking];
- [buttonFolderContextMenu_ cancelTracking];
-}
-
-// Determines the appropriate state for the given situation.
-+ (bookmarks::VisualState)visualStateToShowNormalBar:(BOOL)showNormalBar
- showDetachedBar:(BOOL)showDetachedBar {
- if (showNormalBar)
- return bookmarks::kShowingState;
- if (showDetachedBar)
- return bookmarks::kDetachedState;
- return bookmarks::kHiddenState;
-}
-
-- (void)moveToVisualState:(bookmarks::VisualState)nextVisualState
- withAnimation:(BOOL)animate {
- BOOL isAnimationRunning = [self isAnimationRunning];
-
- // No-op if the next state is the same as the "current" one, subject to the
- // following conditions:
- // - no animation is running; or
- // - an animation is running and |animate| is YES ([*] if it's NO, we'd want
- // to cancel the animation and jump to the final state).
- if ((nextVisualState == visualState_) && (!isAnimationRunning || animate))
- return;
-
- // If an animation is running, we want to finalize it. Otherwise we'd have to
- // be able to animate starting from the middle of one type of animation. We
- // assume that animations that we know about can be "reversed".
- if (isAnimationRunning) {
- // Don't cancel if we're going to reverse the animation.
- if (nextVisualState != lastVisualState_) {
- [self stopCurrentAnimation];
- [self finalizeVisualState];
- }
-
- // If we're in case [*] above, we can stop here.
- if (nextVisualState == visualState_)
- return;
- }
-
- // Now update with the new state change.
- lastVisualState_ = visualState_;
- visualState_ = nextVisualState;
-
- // Animate only if told to and if bar is enabled.
- if (animate && !ignoreAnimations_ && barIsEnabled_) {
- [self closeAllBookmarkFolders];
- // Take care of any animation cases we know how to handle.
-
- // We know how to handle hidden <-> normal, normal <-> detached....
- if ([self isAnimatingBetweenState:bookmarks::kHiddenState
- andState:bookmarks::kShowingState] ||
- [self isAnimatingBetweenState:bookmarks::kShowingState
- andState:bookmarks::kDetachedState]) {
- [delegate_ bookmarkBar:self willAnimateFromState:lastVisualState_
- toState:visualState_];
- [self showBookmarkBarWithAnimation:YES];
- return;
- }
-
- // If we ever need any other animation cases, code would go here.
- // Let any animation cases which we don't know how to handle fall through to
- // the unanimated case.
- }
-
- // Just jump to the state.
- [self finalizeVisualState];
-}
-
-// N.B.: |-moveToVisualState:...| will check if this should be a no-op or not.
-- (void)updateAndShowNormalBar:(BOOL)showNormalBar
- showDetachedBar:(BOOL)showDetachedBar
- withAnimation:(BOOL)animate {
- bookmarks::VisualState newVisualState =
- [BookmarkBarController visualStateToShowNormalBar:showNormalBar
- showDetachedBar:showDetachedBar];
- [self moveToVisualState:newVisualState
- withAnimation:animate && !ignoreAnimations_];
-}
-
-// (Private)
-- (void)finalizeVisualState {
- // We promise that our delegate that the variables will be finalized before
- // the call to |-bookmarkBar:didChangeFromState:toState:|.
- bookmarks::VisualState oldVisualState = lastVisualState_;
- lastVisualState_ = bookmarks::kInvalidState;
-
- // Notify our delegate.
- [delegate_ bookmarkBar:self didChangeFromState:oldVisualState
- toState:visualState_];
-
- // Update ourselves visually.
- [self updateVisibility];
-}
-
-// (Private)
-- (void)stopCurrentAnimation {
- [[self animatableView] stopAnimation];
-}
-
-// Delegate method for |AnimatableView| (a superclass of
-// |BookmarkBarToolbarView|).
-- (void)animationDidEnd:(NSAnimation*)animation {
- [self finalizeVisualState];
-}
-
-- (void)reconfigureBookmarkBar {
- [self redistributeButtonsOnBarAsNeeded];
- [self positionOffTheSideButton];
- [self configureOffTheSideButtonContentsAndVisibility];
- [self centerNoItemsLabel];
-}
-
-// Determine if the given |view| can completely fit within the constraint of
-// maximum x, given by |maxViewX|, and, if not, narrow the view up to a minimum
-// width. If the minimum width is not achievable then hide the view. Return YES
-// if the view was hidden.
-- (BOOL)shrinkOrHideView:(NSView*)view forMaxX:(CGFloat)maxViewX {
- BOOL wasHidden = NO;
- // See if the view needs to be narrowed.
- NSRect frame = [view frame];
- if (NSMaxX(frame) > maxViewX) {
- // Resize if more than 30 pixels are showing, otherwise hide.
- if (NSMinX(frame) + 30.0 < maxViewX) {
- frame.size.width = maxViewX - NSMinX(frame);
- [view setFrame:frame];
- } else {
- [view setHidden:YES];
- wasHidden = YES;
- }
- }
- return wasHidden;
-}
-
-// Adjust the horizontal width and the visibility of the "For quick access"
-// text field and "Import bookmarks..." button based on the current width
-// of the containing |buttonView_| (which is affected by window width).
-- (void)adjustNoItemContainerWidthsForMaxX:(CGFloat)maxViewX {
- if (![[buttonView_ noItemContainer] isHidden]) {
- // Reset initial frames for the two items, then adjust as necessary.
- NSTextField* noItemTextfield = [buttonView_ noItemTextfield];
- [noItemTextfield setFrame:originalNoItemsRect_];
- [noItemTextfield setHidden:NO];
- NSButton* importBookmarksButton = [buttonView_ importBookmarksButton];
- [importBookmarksButton setFrame:originalImportBookmarksRect_];
- [importBookmarksButton setHidden:NO];
- // Check each to see if they need to be shrunk or hidden.
- if ([self shrinkOrHideView:importBookmarksButton forMaxX:maxViewX])
- [self shrinkOrHideView:noItemTextfield forMaxX:maxViewX];
- }
-}
-
-- (void)redistributeButtonsOnBarAsNeeded {
- const BookmarkNode* node = bookmarkModel_->GetBookmarkBarNode();
- NSInteger barCount = node->GetChildCount();
-
- // Determine the current maximum extent of the visible buttons.
- CGFloat maxViewX = NSMaxX([[self view] bounds]);
- NSButton* otherBookmarksButton = otherBookmarksButton_.get();
- // If necessary, pull in the width to account for the Other Bookmarks button.
- if (otherBookmarksButton_)
- maxViewX = [otherBookmarksButton frame].origin.x -
- bookmarks::kBookmarkHorizontalPadding;
- // If we're already overflowing, then we need to account for the chevron.
- if (barCount > displayedButtonCount_)
- maxViewX = [offTheSideButton_ frame].origin.x -
- bookmarks::kBookmarkHorizontalPadding;
-
- // As a result of pasting or dragging, the bar may now have more buttons
- // than will fit so remove any which overflow. They will be shown in
- // the off-the-side folder.
- while (displayedButtonCount_ > 0) {
- BookmarkButton* button = [buttons_ lastObject];
- if (NSMaxX([button frame]) < maxViewX)
- break;
- [buttons_ removeLastObject];
- [button setDelegate:nil];
- [button removeFromSuperview];
- --displayedButtonCount_;
- }
-
- // As a result of cutting, deleting and dragging, the bar may now have room
- // for more buttons.
- int xOffset = displayedButtonCount_ > 0 ?
- NSMaxX([[buttons_ lastObject] frame]) +
- bookmarks::kBookmarkHorizontalPadding : 0;
- for (int i = displayedButtonCount_; i < barCount; ++i) {
- const BookmarkNode* child = node->GetChild(i);
- BookmarkButton* button = [self buttonForNode:child xOffset:&xOffset];
- // If we're testing against the last possible button then account
- // for the chevron no longer needing to be shown.
- if (i == barCount + 1)
- maxViewX += NSWidth([offTheSideButton_ frame]) +
- bookmarks::kBookmarkHorizontalPadding;
- if (NSMaxX([button frame]) >= maxViewX)
- break;
- ++displayedButtonCount_;
- [buttons_ addObject:button];
- [buttonView_ addSubview:button];
- }
-
- // While we're here, adjust the horizontal width and the visibility
- // of the "For quick access" and "Import bookmarks..." text fields.
- if (![buttons_ count])
- [self adjustNoItemContainerWidthsForMaxX:maxViewX];
-}
-
-#pragma mark Private Methods Exposed for Testing
-
-- (BookmarkBarView*)buttonView {
- return buttonView_;
-}
-
-- (NSMutableArray*)buttons {
- return buttons_.get();
-}
-
-- (NSButton*)offTheSideButton {
- return offTheSideButton_;
-}
-
-- (BOOL)offTheSideButtonIsHidden {
- return [offTheSideButton_ isHidden];
-}
-
-- (BookmarkButton*)otherBookmarksButton {
- return otherBookmarksButton_.get();
-}
-
-- (BookmarkBarFolderController*)folderController {
- return folderController_;
-}
-
-- (id)folderTarget {
- return folderTarget_.get();
-}
-
-- (int)displayedButtonCount {
- return displayedButtonCount_;
-}
-
-// Delete all buttons (bookmarks, chevron, "other bookmarks") from the
-// bookmark bar; reset knowledge of bookmarks.
-- (void)clearBookmarkBar {
- for (BookmarkButton* button in buttons_.get()) {
- [button setDelegate:nil];
- [button removeFromSuperview];
- }
- [buttons_ removeAllObjects];
- [self clearMenuTagMap];
- displayedButtonCount_ = 0;
-
- // Make sure there are no stale pointers in the pasteboard. This
- // can be important if a bookmark is deleted (via bookmark sync)
- // while in the middle of a drag. The "drag completed" code
- // (e.g. [BookmarkBarView performDragOperationForBookmarkButton:]) is
- // careful enough to bail if there is no data found at "drop" time.
- //
- // Unfortunately the clearContents selector is 10.6 only. The best
- // we can do is make sure something else is present in place of the
- // stale bookmark.
- NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- [pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
- [pboard setString:@"" forType:NSStringPboardType];
-}
-
-// Return an autoreleased NSCell suitable for a bookmark button.
-// TODO(jrg): move much of the cell config into the BookmarkButtonCell class.
-- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node {
- NSImage* image = node ? [self favIconForNode:node] : nil;
- NSMenu* menu = node && node->is_folder() ? buttonFolderContextMenu_ :
- buttonContextMenu_;
- BookmarkButtonCell* cell = [BookmarkButtonCell buttonCellForNode:node
- contextMenu:menu
- cellText:nil
- cellImage:image];
- [cell setTag:kStandardButtonTypeWithLimitedClickFeedback];
-
- // Note: a quirk of setting a cell's text color is that it won't work
- // until the cell is associated with a button, so we can't theme the cell yet.
-
- return cell;
-}
-
-// Returns a frame appropriate for the given bookmark cell, suitable
-// for creating an NSButton that will contain it. |xOffset| is the X
-// offset for the frame; it is increased to be an appropriate X offset
-// for the next button.
-- (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell
- xOffset:(int*)xOffset {
- DCHECK(xOffset);
- NSRect bounds = [buttonView_ bounds];
- bounds.size.height = bookmarks::kBookmarkButtonHeight;
-
- NSRect frame = NSInsetRect(bounds,
- bookmarks::kBookmarkHorizontalPadding,
- bookmarks::kBookmarkVerticalPadding);
- frame.size.width = [self widthForBookmarkButtonCell:cell];
-
- // Add an X offset based on what we've already done
- frame.origin.x += *xOffset;
-
- // And up the X offset for next time.
- *xOffset = NSMaxX(frame);
-
- return frame;
-}
-
-// A bookmark button's contents changed. Check for growth
-// (e.g. increase the width up to the maximum). If we grew, move
-// other bookmark buttons over.
-- (void)checkForBookmarkButtonGrowth:(NSButton*)button {
- NSRect frame = [button frame];
- CGFloat desiredSize = [self widthForBookmarkButtonCell:[button cell]];
- CGFloat delta = desiredSize - frame.size.width;
- if (delta) {
- frame.size.width = desiredSize;
- [button setFrame:frame];
- for (NSButton* button in buttons_.get()) {
- NSRect buttonFrame = [button frame];
- if (buttonFrame.origin.x > frame.origin.x) {
- buttonFrame.origin.x += delta;
- [button setFrame:buttonFrame];
- }
- }
- }
- // We may have just crossed a threshold to enable the off-the-side
- // button.
- [self configureOffTheSideButtonContentsAndVisibility];
-}
-
-// Called when our controlled frame has changed size.
-- (void)frameDidChange {
- if (!bookmarkModel_->IsLoaded())
- return;
- [self updateTheme:[[[self view] window] themeProvider]];
- [self reconfigureBookmarkBar];
-}
-
-// Given a NSMenuItem tag, return the appropriate bookmark node id.
-- (int64)nodeIdFromMenuTag:(int32)tag {
- return menuTagMap_[tag];
-}
-
-// Create and return a new tag for the given node id.
-- (int32)menuTagFromNodeId:(int64)menuid {
- int tag = seedId_++;
- menuTagMap_[tag] = menuid;
- return tag;
-}
-
-// Return the BookmarkNode associated with the given NSMenuItem. Can
-// return NULL which means "do nothing". One case where it would
-// return NULL is if the bookmark model gets modified while you have a
-// context menu open.
-- (const BookmarkNode*)nodeFromMenuItem:(id)sender {
- const BookmarkNode* node = NULL;
- BookmarkMenu* menu = (BookmarkMenu*)[sender menu];
- if ([menu isKindOfClass:[BookmarkMenu class]]) {
- int64 id = [menu id];
- node = bookmarkModel_->GetNodeByID(id);
- }
- return node;
-}
-
-// Adapt appearance of buttons to the current theme. Called after
-// theme changes, or when our view is added to the view hierarchy.
-// Oddly, the view pings us instead of us pinging our view. This is
-// because our trigger is an [NSView viewWillMoveToWindow:], which the
-// controller doesn't normally know about. Otherwise we don't have
-// access to the theme before we know what window we will be on.
-- (void)updateTheme:(ThemeProvider*)themeProvider {
- if (!themeProvider)
- return;
- NSColor* color =
- themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT,
- true);
- for (BookmarkButton* button in buttons_.get()) {
- BookmarkButtonCell* cell = [button cell];
- [cell setTextColor:color];
- }
- [[otherBookmarksButton_ cell] setTextColor:color];
-}
-
-// Return YES if the event indicates an exit from the bookmark bar
-// folder menus. E.g. "click outside" of the area we are watching.
-// At this time we are watching the area that includes all popup
-// bookmark folder windows.
-- (BOOL)isEventAnExitEvent:(NSEvent*)event {
- NSWindow* eventWindow = [event window];
- NSWindow* myWindow = [[self view] window];
- switch ([event type]) {
- case NSLeftMouseDown:
- case NSRightMouseDown:
- // If the click is in my window but NOT in the bookmark bar, consider
- // it a click 'outside'. Clicks directly on an active button (i.e. one
- // that is a folder and for which its folder menu is showing) are 'in'.
- // All other clicks on the bookmarks bar are counted as 'outside'
- // because they should close any open bookmark folder menu.
- if (eventWindow == myWindow) {
- NSView* hitView =
- [[eventWindow contentView] hitTest:[event locationInWindow]];
- if (hitView == [folderController_ parentButton])
- return NO;
- if (![hitView isDescendantOf:[self view]] || hitView == buttonView_)
- return YES;
- }
- // If a click in a bookmark bar folder window and that isn't
- // one of my bookmark bar folders, YES is click outside.
- if (![eventWindow isKindOfClass:[BookmarkBarFolderWindow
- class]]) {
- return YES;
- }
- break;
- case NSKeyDown:
- case NSKeyUp:
- // Any key press ends things.
- return YES;
- case NSLeftMouseDragged:
- // We can get here with the following sequence:
- // - open a bookmark folder
- // - right-click (and unclick) on it to open context menu
- // - move mouse to window titlebar then click-drag it by the titlebar
- // http://crbug.com/49333
- return YES;
- default:
- break;
- }
- return NO;
-}
-
-#pragma mark Drag & Drop
-
-// Find something like std::is_between<T>? I can't believe one doesn't exist.
-static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
- return ((value >= low) && (value <= high));
-}
-
-// Return the proposed drop target for a hover open button from the
-// given array, or nil if none. We use this for distinguishing
-// between a hover-open candidate or drop-indicator draw.
-// Helper for buttonForDroppingOnAtPoint:.
-// Get UI review on "middle half" ness.
-// http://crbug.com/36276
-- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point
- fromArray:(NSArray*)array {
- for (BookmarkButton* button in array) {
- // Break early if we've gone too far.
- if ((NSMinX([button frame]) > point.x) || (![button superview]))
- return nil;
- // Careful -- this only applies to the bar with horiz buttons.
- // Intentionally NOT using NSPointInRect() so that scrolling into
- // a submenu doesn't cause it to be closed.
- if (ValueInRangeInclusive(NSMinX([button frame]),
- point.x,
- NSMaxX([button frame]))) {
- // Over a button but let's be a little more specific (make sure
- // it's over the middle half, not just over it).
- NSRect frame = [button frame];
- NSRect middleHalfOfButton = NSInsetRect(frame, frame.size.width / 4, 0);
- if (ValueInRangeInclusive(NSMinX(middleHalfOfButton),
- point.x,
- NSMaxX(middleHalfOfButton))) {
- // It makes no sense to drop on a non-folder; there is no hover.
- if (![button isFolder])
- return nil;
- // Got it!
- return button;
- } else {
- // Over a button but not over the middle half.
- return nil;
- }
- }
- }
- // Not hovering over a button.
- return nil;
-}
-
-// Return the proposed drop target for a hover open button, or nil if
-// none. Works with both the bookmark buttons and the "Other
-// Bookmarks" button. Point is in [self view] coordinates.
-- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point {
- point = [[self view] convertPoint:point
- fromView:[[[self view] window] contentView]];
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point
- fromArray:buttons_.get()];
- // One more chance -- try "Other Bookmarks" and "off the side" (if visible).
- // This is different than BookmarkBarFolderController.
- if (!button) {
- NSMutableArray* array = [NSMutableArray array];
- if (![self offTheSideButtonIsHidden])
- [array addObject:offTheSideButton_];
- [array addObject:otherBookmarksButton_];
- button = [self buttonForDroppingOnAtPoint:point
- fromArray:array];
- }
- return button;
-}
-
-- (int)indexForDragToPoint:(NSPoint)point {
- // TODO(jrg): revisit position info based on UI team feedback.
- // dropLocation is in bar local coordinates.
- NSPoint dropLocation =
- [[self view] convertPoint:point
- fromView:[[[self view] window] contentView]];
- BookmarkButton* buttonToTheRightOfDraggedButton = nil;
- for (BookmarkButton* button in buttons_.get()) {
- CGFloat midpoint = NSMidX([button frame]);
- if (dropLocation.x <= midpoint) {
- buttonToTheRightOfDraggedButton = button;
- break;
- }
- }
- if (buttonToTheRightOfDraggedButton) {
- const BookmarkNode* afterNode =
- [buttonToTheRightOfDraggedButton bookmarkNode];
- DCHECK(afterNode);
- int index = afterNode->GetParent()->IndexOfChild(afterNode);
- // Make sure we don't get confused by buttons which aren't visible.
- return std::min(index, displayedButtonCount_);
- }
-
- // If nothing is to my right I am at the end!
- return displayedButtonCount_;
-}
-
-// TODO(mrossetti,jrg): Yet more duplicated code.
-// http://crbug.com/35966
-- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
- to:(NSPoint)point
- copy:(BOOL)copy {
- DCHECK(sourceNode);
- // Drop destination.
- const BookmarkNode* destParent = NULL;
- int destIndex = 0;
-
- // First check if we're dropping on a button. If we have one, and
- // it's a folder, drop in it.
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
- if ([button isFolder]) {
- destParent = [button bookmarkNode];
- // Drop it at the end.
- destIndex = [button bookmarkNode]->GetChildCount();
- } else {
- // Else we're dropping somewhere on the bar, so find the right spot.
- destParent = bookmarkModel_->GetBookmarkBarNode();
- destIndex = [self indexForDragToPoint:point];
- }
-
- // Be sure we don't try and drop a folder into itself.
- if (sourceNode != destParent) {
- if (copy)
- bookmarkModel_->Copy(sourceNode, destParent, destIndex);
- else
- bookmarkModel_->Move(sourceNode, destParent, destIndex);
- }
-
- [self closeFolderAndStopTrackingMenus];
-
- // Movement of a node triggers observers (like us) to rebuild the
- // bar so we don't have to do so explicitly.
-
- return YES;
-}
-
-- (void)draggingEnded:(id<NSDraggingInfo>)info {
- [self closeFolderAndStopTrackingMenus];
-}
-
-#pragma mark Bridge Notification Handlers
-
-// TODO(jrg): for now this is brute force.
-- (void)loaded:(BookmarkModel*)model {
- DCHECK(model == bookmarkModel_);
- if (!model->IsLoaded())
- return;
-
- // If this is a rebuild request while we have a folder open, close it.
- // TODO(mrossetti): Eliminate the need for this because it causes the folder
- // menu to disappear after a cut/copy/paste/delete change.
- // See: http://crbug.com/36614
- if (folderController_)
- [self closeAllBookmarkFolders];
-
- // Brute force nuke and build.
- savedFrameWidth_ = NSWidth([[self view] frame]);
- const BookmarkNode* node = model->GetBookmarkBarNode();
- [self clearBookmarkBar];
- [self addNodesToButtonList:node];
- [self createOtherBookmarksButton];
- [self updateTheme:[[[self view] window] themeProvider]];
- [self positionOffTheSideButton];
- [self addNonBookmarkButtonsToView];
- [self addButtonsToView];
- [self configureOffTheSideButtonContentsAndVisibility];
- [self setNodeForBarMenu];
-}
-
-- (void)beingDeleted:(BookmarkModel*)model {
- // The browser may be being torn down; little is safe to do. As an
- // example, it may not be safe to clear the pasteboard.
- // http://crbug.com/38665
-}
-
-- (void)nodeAdded:(BookmarkModel*)model
- parent:(const BookmarkNode*)newParent index:(int)newIndex {
- // If a context menu is open, close it.
- [self cancelMenuTracking];
-
- const BookmarkNode* newNode = newParent->GetChild(newIndex);
- id<BookmarkButtonControllerProtocol> newController =
- [self controllerForNode:newParent];
- [newController addButtonForNode:newNode atIndex:newIndex];
- // If we go from 0 --> 1 bookmarks we may need to hide the
- // "bookmarks go here" text container.
- [self showOrHideNoItemContainerForNode:model->GetBookmarkBarNode()];
-}
-
-// TODO(jrg): for now this is brute force.
-- (void)nodeChanged:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- [self loaded:model];
-}
-
-- (void)nodeMoved:(BookmarkModel*)model
- oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
- newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex {
- const BookmarkNode* movedNode = newParent->GetChild(newIndex);
- id<BookmarkButtonControllerProtocol> oldController =
- [self controllerForNode:oldParent];
- id<BookmarkButtonControllerProtocol> newController =
- [self controllerForNode:newParent];
- if (newController == oldController) {
- [oldController moveButtonFromIndex:oldIndex toIndex:newIndex];
- } else {
- [oldController removeButton:oldIndex animate:NO];
- [newController addButtonForNode:movedNode atIndex:newIndex];
- }
- // If the bar is one of the parents we may need to update the visibility
- // of the "bookmarks go here" presentation.
- [self showOrHideNoItemContainerForNode:model->GetBookmarkBarNode()];
- // If we moved the only item on the "off the side" menu somewhere
- // else, we may no longer need to show it.
- [self configureOffTheSideButtonContentsAndVisibility];
-}
-
-- (void)nodeRemoved:(BookmarkModel*)model
- parent:(const BookmarkNode*)oldParent index:(int)index {
- // If a context menu is open, close it.
- [self cancelMenuTracking];
-
- // Locate the parent node. The parent may not be showing, in which case
- // we do nothing.
- id<BookmarkButtonControllerProtocol> parentController =
- [self controllerForNode:oldParent];
- [parentController removeButton:index animate:YES];
- // If we go from 1 --> 0 bookmarks we may need to show the
- // "bookmarks go here" text container.
- [self showOrHideNoItemContainerForNode:model->GetBookmarkBarNode()];
- // If we deleted the only item on the "off the side" menu we no
- // longer need to show it.
- [self configureOffTheSideButtonContentsAndVisibility];
-}
-
-// TODO(jrg): linear searching is bad.
-// Need a BookmarkNode-->NSCell mapping.
-//
-// TODO(jrg): if the bookmark bar is open on launch, we see the
-// buttons all placed, then "scooted over" as the favicons load. If
-// this looks bad I may need to change widthForBookmarkButtonCell to
-// add space for an image even if not there on the assumption that
-// favicons will eventually load.
-- (void)nodeFavIconLoaded:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- for (BookmarkButton* button in buttons_.get()) {
- const BookmarkNode* cellnode = [button bookmarkNode];
- if (cellnode == node) {
- [[button cell] setBookmarkCellText:[button title]
- image:[self favIconForNode:node]];
- // Adding an image means we might need more room for the
- // bookmark. Test for it by growing the button (if needed)
- // and shifting everything else over.
- [self checkForBookmarkButtonGrowth:button];
- }
- }
-}
-
-// TODO(jrg): for now this is brute force.
-- (void)nodeChildrenReordered:(BookmarkModel*)model
- node:(const BookmarkNode*)node {
- [self loaded:model];
-}
-
-#pragma mark BookmarkBarState Protocol
-
-// (BookmarkBarState protocol)
-- (BOOL)isVisible {
- return barIsEnabled_ && (visualState_ == bookmarks::kShowingState ||
- visualState_ == bookmarks::kDetachedState ||
- lastVisualState_ == bookmarks::kShowingState ||
- lastVisualState_ == bookmarks::kDetachedState);
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isAnimationRunning {
- return lastVisualState_ != bookmarks::kInvalidState;
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isInState:(bookmarks::VisualState)state {
- return visualState_ == state &&
- lastVisualState_ == bookmarks::kInvalidState;
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isAnimatingToState:(bookmarks::VisualState)state {
- return visualState_ == state &&
- lastVisualState_ != bookmarks::kInvalidState;
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)state {
- return lastVisualState_ == state;
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)fromState
- toState:(bookmarks::VisualState)toState {
- return lastVisualState_ == fromState && visualState_ == toState;
-}
-
-// (BookmarkBarState protocol)
-- (BOOL)isAnimatingBetweenState:(bookmarks::VisualState)fromState
- andState:(bookmarks::VisualState)toState {
- return (lastVisualState_ == fromState && visualState_ == toState) ||
- (visualState_ == fromState && lastVisualState_ == toState);
-}
-
-// (BookmarkBarState protocol)
-- (CGFloat)detachedMorphProgress {
- if ([self isInState:bookmarks::kDetachedState]) {
- return 1;
- }
- if ([self isAnimatingToState:bookmarks::kDetachedState]) {
- return static_cast<CGFloat>(
- [[self animatableView] currentAnimationProgress]);
- }
- if ([self isAnimatingFromState:bookmarks::kDetachedState]) {
- return static_cast<CGFloat>(
- 1 - [[self animatableView] currentAnimationProgress]);
- }
- return 0;
-}
-
-#pragma mark BookmarkBarToolbarViewController Protocol
-
-- (int)currentTabContentsHeight {
- TabContents* tc = browser_->GetSelectedTabContents();
- return tc ? tc->view()->GetContainerSize().height() : 0;
-}
-
-- (ThemeProvider*)themeProvider {
- return browser_->profile()->GetThemeProvider();
-}
-
-#pragma mark BookmarkButtonDelegate Protocol
-
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button {
- [[self folderTarget] fillPasteboard:pboard forDragOfButton:button];
-}
-
-// BookmarkButtonDelegate protocol implementation. When menus are
-// "active" (e.g. you clicked to open one), moving the mouse over
-// another folder button should close the 1st and open the 2nd (like
-// real menus). We detect and act here.
-- (void)mouseEnteredButton:(id)sender event:(NSEvent*)event {
- DCHECK([sender isKindOfClass:[BookmarkButton class]]);
-
- // If folder menus are not being shown, do nothing. This is different from
- // BookmarkBarFolderController's implementation because the bar should NOT
- // automatically open folder menus when the mouse passes over a folder
- // button while the BookmarkBarFolderController DOES automically open
- // a subfolder menu.
- if (!showFolderMenus_)
- return;
-
- // From here down: same logic as BookmarkBarFolderController.
- // TODO(jrg): find a way to share these 4 non-comment lines?
- // http://crbug.com/35966
- // If already opened, then we exited but re-entered the button, so do nothing.
- if ([folderController_ parentButton] == sender)
- return;
- // Else open a new one if it makes sense to do so.
- if ([sender bookmarkNode]->is_folder()) {
- [folderTarget_ openBookmarkFolderFromButton:sender];
- } else {
- // We're over a non-folder bookmark so close any old folders.
- [folderController_ close];
- folderController_ = nil;
- }
-}
-
-// BookmarkButtonDelegate protocol implementation.
-- (void)mouseExitedButton:(id)sender event:(NSEvent*)event {
- // Don't care; do nothing.
- // This is different behavior that the folder menus.
-}
-
-- (NSWindow*)browserWindow {
- return [[self view] window];
-}
-
-- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
- return [self canEditBookmark:[button bookmarkNode]];
-}
-
-- (void)didDragBookmarkToTrash:(BookmarkButton*)button {
- // TODO(mrossetti): Refactor BookmarkBarFolder common code.
- // http://crbug.com/35966
- const BookmarkNode* node = [button bookmarkNode];
- if (node) {
- const BookmarkNode* parent = node->GetParent();
- bookmarkModel_->Remove(parent,
- parent->IndexOfChild(node));
- }
-}
-
-#pragma mark BookmarkButtonControllerProtocol
-
-// Close all bookmark folders. "Folder" here is the fake menu for
-// bookmark folders, not a button context menu.
-- (void)closeAllBookmarkFolders {
- [self watchForExitEvent:NO];
- [folderController_ close];
- folderController_ = nil;
-}
-
-- (void)closeBookmarkFolder:(id)sender {
- // We're the top level, so close one means close them all.
- [self closeAllBookmarkFolders];
-}
-
-- (BookmarkModel*)bookmarkModel {
- return bookmarkModel_;
-}
-
-// TODO(jrg): much of this logic is duped with
-// [BookmarkBarFolderController draggingEntered:] except when noted.
-// http://crbug.com/35966
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- NSPoint point = [info draggingLocation];
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
-
- // Don't allow drops that would result in cycles.
- if (button) {
- NSData* data = [[info draggingPasteboard]
- dataForType:kBookmarkButtonDragType];
- if (data && [info draggingSource]) {
- BookmarkButton* sourceButton = nil;
- [data getBytes:&sourceButton length:sizeof(sourceButton)];
- const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
- const BookmarkNode* destNode = [button bookmarkNode];
- if (destNode->HasAncestor(sourceNode))
- button = nil;
- }
- }
-
- if ([button isFolder]) {
- if (hoverButton_ == button) {
- return NSDragOperationMove; // already open or timed to open
- }
- if (hoverButton_) {
- // Oops, another one triggered or open.
- [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_
- target]];
- // Unlike BookmarkBarFolderController, we do not delay the close
- // of the previous one. Given the lack of diagonal movement,
- // there is no need, and it feels awkward to do so. See
- // comments about kDragHoverCloseDelay in
- // bookmark_bar_folder_controller.mm for more details.
- [[hoverButton_ target] closeBookmarkFolder:hoverButton_];
- hoverButton_.reset();
- }
- hoverButton_.reset([button retain]);
- DCHECK([[hoverButton_ target]
- respondsToSelector:@selector(openBookmarkFolderFromButton:)]);
- [[hoverButton_ target]
- performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:hoverButton_
- afterDelay:bookmarks::kDragHoverOpenDelay];
- }
- if (!button) {
- if (hoverButton_) {
- [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_ target]];
- [[hoverButton_ target] closeBookmarkFolder:hoverButton_];
- hoverButton_.reset();
- }
- }
-
- // Thrown away but kept to be consistent with the draggingEntered: interface.
- return NSDragOperationMove;
-}
-
-- (void)draggingExited:(id<NSDraggingInfo>)info {
- // NOT the same as a cancel --> we may have moved the mouse into the submenu.
- if (hoverButton_) {
- [NSObject cancelPreviousPerformRequestsWithTarget:[hoverButton_ target]];
- hoverButton_.reset();
- }
-}
-
-- (BOOL)dragShouldLockBarVisibility {
- return ![self isInState:bookmarks::kDetachedState] &&
- ![self isAnimatingToState:bookmarks::kDetachedState];
-}
-
-// TODO(mrossetti,jrg): Yet more code dup with BookmarkBarFolderController.
-// http://crbug.com/35966
-- (BOOL)dragButton:(BookmarkButton*)sourceButton
- to:(NSPoint)point
- copy:(BOOL)copy {
- DCHECK([sourceButton isKindOfClass:[BookmarkButton class]]);
- const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
- return [self dragBookmark:sourceNode to:point copy:copy];
-}
-
-- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info {
- BOOL dragged = NO;
- std::vector<const BookmarkNode*> nodes([self retrieveBookmarkNodeData]);
- if (nodes.size()) {
- BOOL copy = !([info draggingSourceOperationMask] & NSDragOperationMove);
- NSPoint dropPoint = [info draggingLocation];
- for (std::vector<const BookmarkNode*>::const_iterator it = nodes.begin();
- it != nodes.end(); ++it) {
- const BookmarkNode* sourceNode = *it;
- dragged = [self dragBookmark:sourceNode to:dropPoint copy:copy];
- }
- }
- return dragged;
-}
-
-- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData {
- std::vector<const BookmarkNode*> dragDataNodes;
- BookmarkNodeData dragData;
- if(dragData.ReadFromDragClipboard()) {
- BookmarkModel* bookmarkModel = [self bookmarkModel];
- Profile* profile = bookmarkModel->profile();
- std::vector<const BookmarkNode*> nodes(dragData.GetNodes(profile));
- dragDataNodes.assign(nodes.begin(), nodes.end());
- }
- return dragDataNodes;
-}
-
-// Return YES if we should show the drop indicator, else NO.
-- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point {
- return ![self buttonForDroppingOnAtPoint:point];
-}
-
-// Return the x position for a drop indicator.
-- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point {
- CGFloat x = 0;
- int destIndex = [self indexForDragToPoint:point];
- int numButtons = displayedButtonCount_;
-
- // If it's a drop strictly between existing buttons ...
- if (destIndex >= 0 && destIndex < numButtons) {
- // ... put the indicator right between the buttons.
- BookmarkButton* button =
- [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex)];
- DCHECK(button);
- NSRect buttonFrame = [button frame];
- x = buttonFrame.origin.x - 0.5 * bookmarks::kBookmarkHorizontalPadding;
-
- // If it's a drop at the end (past the last button, if there are any) ...
- } else if (destIndex == numButtons) {
- // and if it's past the last button ...
- if (numButtons > 0) {
- // ... find the last button, and put the indicator to its right.
- BookmarkButton* button =
- [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex - 1)];
- DCHECK(button);
- NSRect buttonFrame = [button frame];
- x = NSMaxX(buttonFrame) + 0.5 * bookmarks::kBookmarkHorizontalPadding;
-
- // Otherwise, put it right at the beginning.
- } else {
- x = 0.5 * bookmarks::kBookmarkHorizontalPadding;
- }
- } else {
- NOTREACHED();
- }
-
- return x;
-}
-
-- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child {
- // If the bookmarkbar is not in detached mode, lock bar visibility, forcing
- // the overlay to stay open when in fullscreen mode.
- if (![self isInState:bookmarks::kDetachedState] &&
- ![self isAnimatingToState:bookmarks::kDetachedState]) {
- BrowserWindowController* browserController =
- [BrowserWindowController browserWindowControllerForView:[self view]];
- [browserController lockBarVisibilityForOwner:child
- withAnimation:NO
- delay:NO];
- }
-}
-
-- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child {
- // Release bar visibility, allowing the overlay to close if in fullscreen
- // mode.
- BrowserWindowController* browserController =
- [BrowserWindowController browserWindowControllerForView:[self view]];
- [browserController releaseBarVisibilityForOwner:child
- withAnimation:NO
- delay:NO];
-}
-
-// Add a new folder controller as triggered by the given folder button.
-- (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton {
-
- // If doing a close/open, make sure the fullscreen chrome doesn't
- // have a chance to begin animating away in the middle of things.
- BrowserWindowController* browserController =
- [BrowserWindowController browserWindowControllerForView:[self view]];
- // Confirm we're not re-locking with ourself as an owner before locking.
- DCHECK([browserController isBarVisibilityLockedForOwner:self] == NO);
- [browserController lockBarVisibilityForOwner:self
- withAnimation:NO
- delay:NO];
-
- if (folderController_)
- [self closeAllBookmarkFolders];
-
- // Folder controller, like many window controllers, owns itself.
- folderController_ =
- [[BookmarkBarFolderController alloc] initWithParentButton:parentButton
- parentController:nil
- barController:self];
- [folderController_ showWindow:self];
-
- // Only BookmarkBarController has this; the
- // BookmarkBarFolderController does not.
- [self watchForExitEvent:YES];
-
- // No longer need to hold the lock; the folderController_ now owns it.
- [browserController releaseBarVisibilityForOwner:self
- withAnimation:NO
- delay:NO];
-}
-
-- (void)openAll:(const BookmarkNode*)node
- disposition:(WindowOpenDisposition)disposition {
- [self closeFolderAndStopTrackingMenus];
- bookmark_utils::OpenAll([[self view] window],
- browser_->profile(),
- browser_,
- node,
- disposition);
-}
-
-- (void)addButtonForNode:(const BookmarkNode*)node
- atIndex:(NSInteger)buttonIndex {
- int newOffset = 0;
- if (buttonIndex == -1)
- buttonIndex = [buttons_ count]; // New button goes at the end.
- if (buttonIndex <= (NSInteger)[buttons_ count]) {
- if (buttonIndex) {
- BookmarkButton* targetButton = [buttons_ objectAtIndex:buttonIndex - 1];
- NSRect targetFrame = [targetButton frame];
- newOffset = targetFrame.origin.x + NSWidth(targetFrame) +
- bookmarks::kBookmarkHorizontalPadding;
- }
- BookmarkButton* newButton = [self buttonForNode:node xOffset:&newOffset];
- CGFloat xOffset =
- NSWidth([newButton frame]) + bookmarks::kBookmarkHorizontalPadding;
- NSUInteger buttonCount = [buttons_ count];
- for (NSUInteger i = buttonIndex; i < buttonCount; ++i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSPoint buttonOrigin = [button frame].origin;
- buttonOrigin.x += xOffset;
- [button setFrameOrigin:buttonOrigin];
- }
- ++displayedButtonCount_;
- [buttons_ insertObject:newButton atIndex:buttonIndex];
- [buttonView_ addSubview:newButton];
-
- // See if any buttons need to be pushed off to or brought in from the side.
- [self reconfigureBookmarkBar];
- } else {
- // A button from somewhere else (not the bar) is being moved to the
- // off-the-side so insure it gets redrawn if its showing.
- [self reconfigureBookmarkBar];
- [folderController_ reconfigureMenu];
- }
-}
-
-// TODO(mrossetti): Duplicate code with BookmarkBarFolderController.
-// http://crbug.com/35966
-- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point {
- DCHECK([urls count] == [titles count]);
- BOOL nodesWereAdded = NO;
- // Figure out where these new bookmarks nodes are to be added.
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
- const BookmarkNode* destParent = NULL;
- int destIndex = 0;
- if ([button isFolder]) {
- destParent = [button bookmarkNode];
- // Drop it at the end.
- destIndex = [button bookmarkNode]->GetChildCount();
- } else {
- // Else we're dropping somewhere on the bar, so find the right spot.
- destParent = bookmarkModel_->GetBookmarkBarNode();
- destIndex = [self indexForDragToPoint:point];
- }
-
- // Don't add the bookmarks if the destination index shows an error.
- if (destIndex >= 0) {
- // Create and add the new bookmark nodes.
- size_t urlCount = [urls count];
- for (size_t i = 0; i < urlCount; ++i) {
- GURL gurl;
- const char* string = [[urls objectAtIndex:i] UTF8String];
- if (string)
- gurl = GURL(string);
- // We only expect to receive valid URLs.
- DCHECK(gurl.is_valid());
- if (gurl.is_valid()) {
- bookmarkModel_->AddURL(destParent,
- destIndex++,
- base::SysNSStringToUTF16(
- [titles objectAtIndex:i]),
- gurl);
- nodesWereAdded = YES;
- }
- }
- }
- return nodesWereAdded;
-}
-
-// TODO(mrossetti): jrg wants this broken up into smaller functions.
-- (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {
- if (fromIndex != toIndex) {
- NSInteger buttonCount = (NSInteger)[buttons_ count];
- if (toIndex == -1)
- toIndex = buttonCount;
- // See if we have a simple move within the bar, which will be the case if
- // both button indexes are in the visible space.
- if (fromIndex < buttonCount && toIndex < buttonCount) {
- BookmarkButton* movedButton = [buttons_ objectAtIndex:fromIndex];
- NSRect movedFrame = [movedButton frame];
- NSPoint toOrigin = movedFrame.origin;
- CGFloat xOffset =
- NSWidth(movedFrame) + bookmarks::kBookmarkHorizontalPadding;
- // Hide the button to reduce flickering while drawing the window.
- [movedButton setHidden:YES];
- [buttons_ removeObjectAtIndex:fromIndex];
- if (fromIndex < toIndex) {
- // Move the button from left to right within the bar.
- BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex - 1];
- NSRect toFrame = [targetButton frame];
- toOrigin.x = toFrame.origin.x - NSWidth(movedFrame) + NSWidth(toFrame);
- for (NSInteger i = fromIndex; i < toIndex; ++i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect frame = [button frame];
- frame.origin.x -= xOffset;
- [button setFrameOrigin:frame.origin];
- }
- } else {
- // Move the button from right to left within the bar.
- BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex];
- toOrigin = [targetButton frame].origin;
- for (NSInteger i = fromIndex - 1; i >= toIndex; --i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect buttonFrame = [button frame];
- buttonFrame.origin.x += xOffset;
- [button setFrameOrigin:buttonFrame.origin];
- }
- }
- [buttons_ insertObject:movedButton atIndex:toIndex];
- [movedButton setFrameOrigin:toOrigin];
- [movedButton setHidden:NO];
- } else if (fromIndex < buttonCount) {
- // A button is being removed from the bar and added to off-the-side.
- // By now the node has already been inserted into the model so the
- // button to be added is represented by |toIndex|. Things get
- // complicated because the off-the-side is showing and must be redrawn
- // while possibly re-laying out the bookmark bar.
- [self removeButton:fromIndex animate:NO];
- [self reconfigureBookmarkBar];
- [folderController_ reconfigureMenu];
- } else if (toIndex < buttonCount) {
- // A button is being added to the bar and removed from off-the-side.
- // By now the node has already been inserted into the model so the
- // button to be added is represented by |toIndex|.
- const BookmarkNode* node = bookmarkModel_->GetBookmarkBarNode();
- const BookmarkNode* movedNode = node->GetChild(toIndex);
- DCHECK(movedNode);
- [self addButtonForNode:movedNode atIndex:toIndex];
- [self reconfigureBookmarkBar];
- } else {
- // A button is being moved within the off-the-side.
- fromIndex -= buttonCount;
- toIndex -= buttonCount;
- [folderController_ moveButtonFromIndex:fromIndex toIndex:toIndex];
- }
- }
-}
-
-- (void)removeButton:(NSInteger)buttonIndex animate:(BOOL)animate {
- if (buttonIndex < (NSInteger)[buttons_ count]) {
- // The button being removed is showing in the bar.
- BookmarkButton* oldButton = [buttons_ objectAtIndex:buttonIndex];
- if (oldButton == [folderController_ parentButton]) {
- // If we are deleting a button whose folder is currently open, close it!
- [self closeAllBookmarkFolders];
- }
- NSPoint poofPoint = [oldButton screenLocationForRemoveAnimation];
- NSRect oldFrame = [oldButton frame];
- [oldButton setDelegate:nil];
- [oldButton removeFromSuperview];
- if (animate && !ignoreAnimations_ && [self isVisible])
- NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
- NSZeroSize, nil, nil, nil);
- CGFloat xOffset = NSWidth(oldFrame) + bookmarks::kBookmarkHorizontalPadding;
- [buttons_ removeObjectAtIndex:buttonIndex];
- NSUInteger buttonCount = [buttons_ count];
- for (NSUInteger i = buttonIndex; i < buttonCount; ++i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect buttonFrame = [button frame];
- buttonFrame.origin.x -= xOffset;
- [button setFrame:buttonFrame];
- // If this button is showing its menu then we need to move the menu, too.
- if (button == [folderController_ parentButton])
- [folderController_ offsetFolderMenuWindow:NSMakeSize(xOffset, 0.0)];
- }
- --displayedButtonCount_;
- [self reconfigureBookmarkBar];
- } else if (folderController_ &&
- [folderController_ parentButton] == offTheSideButton_) {
- // The button being removed is in the OTS (off-the-side) and the OTS
- // menu is showing so we need to remove the button.
- NSInteger index = buttonIndex - displayedButtonCount_;
- [folderController_ removeButton:index animate:YES];
- }
-}
-
-- (id<BookmarkButtonControllerProtocol>)controllerForNode:
- (const BookmarkNode*)node {
- // See if it's in the bar, then if it is in the hierarchy of visible
- // folder menus.
- if (bookmarkModel_->GetBookmarkBarNode() == node)
- return self;
- return [folderController_ controllerForNode:node];
-}
-
-#pragma mark BookmarkButtonControllerProtocol
-
-// NOT an override of a standard Cocoa call made to NSViewControllers.
-- (void)hookForEvent:(NSEvent*)theEvent {
- if ([self isEventAnExitEvent:theEvent])
- [self closeFolderAndStopTrackingMenus];
-}
-
-#pragma mark TestingAPI Only
-
-- (NSMenu*)buttonContextMenu {
- return buttonContextMenu_;
-}
-
-// Intentionally ignores ownership issues; used for testing and we try
-// to minimize touching the object passed in (likely a mock).
-- (void)setButtonContextMenu:(id)menu {
- buttonContextMenu_ = menu;
-}
-
-- (void)setIgnoreAnimations:(BOOL)ignore {
- ignoreAnimations_ = ignore;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
deleted file mode 100644
index 2d72804..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ /dev/null
@@ -1,2169 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "app/theme_provider.h"
-#include "base/basictypes.h"
-#include "base/scoped_nsobject.h"
-#include "base/string16.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "chrome/browser/cocoa/test_event_utils.h"
-#import "chrome/browser/cocoa/view_resizer_pong.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/model_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-#import "third_party/ocmock/OCMock/OCMock.h"
-
-// Just like a BookmarkBarController but openURL: is stubbed out.
-@interface BookmarkBarControllerNoOpen : BookmarkBarController {
- @public
- std::vector<GURL> urls_;
- std::vector<WindowOpenDisposition> dispositions_;
-}
-@end
-
-@implementation BookmarkBarControllerNoOpen
-- (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition {
- urls_.push_back(url);
- dispositions_.push_back(disposition);
-}
-- (void)clear {
- urls_.clear();
- dispositions_.clear();
-}
-@end
-
-
-// NSCell that is pre-provided with a desired size that becomes the
-// return value for -(NSSize)cellSize:.
-@interface CellWithDesiredSize : NSCell {
- @private
- NSSize cellSize_;
-}
-@property (nonatomic, readonly) NSSize cellSize;
-@end
-
-@implementation CellWithDesiredSize
-
-@synthesize cellSize = cellSize_;
-
-- (id)initTextCell:(NSString*)string desiredSize:(NSSize)size {
- if ((self = [super initTextCell:string])) {
- cellSize_ = size;
- }
- return self;
-}
-
-@end
-
-// Remember the number of times we've gotten a frameDidChange notification.
-@interface BookmarkBarControllerTogglePong : BookmarkBarControllerNoOpen {
- @private
- int toggles_;
-}
-@property (nonatomic, readonly) int toggles;
-@end
-
-@implementation BookmarkBarControllerTogglePong
-
-@synthesize toggles = toggles_;
-
-- (void)frameDidChange {
- toggles_++;
-}
-
-@end
-
-// Remembers if a notification callback was called.
-@interface BookmarkBarControllerNotificationPong : BookmarkBarControllerNoOpen {
- BOOL windowWillCloseReceived_;
- BOOL windowDidResignKeyReceived_;
-}
-@property (nonatomic, readonly) BOOL windowWillCloseReceived;
-@property (nonatomic, readonly) BOOL windowDidResignKeyReceived;
-@end
-
-@implementation BookmarkBarControllerNotificationPong
-@synthesize windowWillCloseReceived = windowWillCloseReceived_;
-@synthesize windowDidResignKeyReceived = windowDidResignKeyReceived_;
-
-// Override NSNotificationCenter callback.
-- (void)parentWindowWillClose:(NSNotification*)notification {
- windowWillCloseReceived_ = YES;
-}
-
-// NSNotificationCenter callback.
-- (void)parentWindowDidResignKey:(NSNotification*)notification {
- windowDidResignKeyReceived_ = YES;
-}
-@end
-
-// Remembers if and what kind of openAll was performed.
-@interface BookmarkBarControllerOpenAllPong : BookmarkBarControllerNoOpen {
- WindowOpenDisposition dispositionDetected_;
-}
-@property (nonatomic) WindowOpenDisposition dispositionDetected;
-@end
-
-@implementation BookmarkBarControllerOpenAllPong
-@synthesize dispositionDetected = dispositionDetected_;
-
-// Intercede for the openAll:disposition: method.
-- (void)openAll:(const BookmarkNode*)node
- disposition:(WindowOpenDisposition)disposition {
- [self setDispositionDetected:disposition];
-}
-
-@end
-
-// Just like a BookmarkBarController but intercedes when providing
-// pasteboard drag data.
-@interface BookmarkBarControllerDragData : BookmarkBarController {
- const BookmarkNode* dragDataNode_; // Weak
-}
-- (void)setDragDataNode:(const BookmarkNode*)node;
-@end
-
-@implementation BookmarkBarControllerDragData
-
-- (id)initWithBrowser:(Browser*)browser
- initialWidth:(CGFloat)initialWidth
- delegate:(id<BookmarkBarControllerDelegate>)delegate
- resizeDelegate:(id<ViewResizer>)resizeDelegate {
- if ((self = [super initWithBrowser:browser
- initialWidth:initialWidth
- delegate:delegate
- resizeDelegate:resizeDelegate])) {
- dragDataNode_ = NULL;
- }
- return self;
-}
-
-- (void)setDragDataNode:(const BookmarkNode*)node {
- dragDataNode_ = node;
-}
-
-- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData {
- std::vector<const BookmarkNode*> dragDataNodes;
- if(dragDataNode_) {
- dragDataNodes.push_back(dragDataNode_);
- }
- return dragDataNodes;
-}
-
-@end
-
-
-class FakeTheme : public ThemeProvider {
- public:
- FakeTheme(NSColor* color) : color_(color) { }
- scoped_nsobject<NSColor> color_;
-
- virtual void Init(Profile* profile) { }
- virtual SkBitmap* GetBitmapNamed(int id) const { return nil; }
- virtual SkColor GetColor(int id) const { return SkColor(); }
- virtual bool GetDisplayProperty(int id, int* result) const { return false; }
- virtual bool ShouldUseNativeFrame() const { return false; }
- virtual bool HasCustomImage(int id) const { return false; }
- virtual RefCountedMemory* GetRawData(int id) const { return NULL; }
- virtual NSImage* GetNSImageNamed(int id, bool allow_default) const {
- return nil;
- }
- virtual NSColor* GetNSImageColorNamed(int id, bool allow_default) const {
- return nil;
- }
- virtual NSColor* GetNSColor(int id, bool allow_default) const {
- return color_.get();
- }
- virtual NSColor* GetNSColorTint(int id, bool allow_default) const {
- return nil;
- }
- virtual NSGradient* GetNSGradient(int id) const {
- return nil;
- }
-};
-
-
-@interface FakeDragInfo : NSObject {
- @public
- NSPoint dropLocation_;
- NSDragOperation sourceMask_;
-}
-@property (nonatomic, assign) NSPoint dropLocation;
-- (void)setDraggingSourceOperationMask:(NSDragOperation)mask;
-@end
-
-@implementation FakeDragInfo
-
-@synthesize dropLocation = dropLocation_;
-
-- (id)init {
- if ((self = [super init])) {
- dropLocation_ = NSZeroPoint;
- sourceMask_ = NSDragOperationMove;
- }
- return self;
-}
-
-// NSDraggingInfo protocol functions.
-
-- (id)draggingPasteboard {
- return self;
-}
-
-- (id)draggingSource {
- return self;
-}
-
-- (NSDragOperation)draggingSourceOperationMask {
- return sourceMask_;
-}
-
-- (NSPoint)draggingLocation {
- return dropLocation_;
-}
-
-// Other functions.
-
-- (void)setDraggingSourceOperationMask:(NSDragOperation)mask {
- sourceMask_ = mask;
-}
-
-@end
-
-
-namespace {
-
-class BookmarkBarControllerTestBase : public CocoaTest {
- public:
- BrowserTestHelper helper_;
- scoped_nsobject<NSView> parent_view_;
- scoped_nsobject<ViewResizerPong> resizeDelegate_;
-
- BookmarkBarControllerTestBase() {
- resizeDelegate_.reset([[ViewResizerPong alloc] init]);
- NSRect parent_frame = NSMakeRect(0, 0, 800, 50);
- parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]);
- [parent_view_ setHidden:YES];
- }
-
- void InstallAndToggleBar(BookmarkBarController* bar) {
- // Force loading of the nib.
- [bar view];
- // Awkwardness to look like we've been installed.
- for (NSView* subView in [parent_view_ subviews])
- [subView removeFromSuperview];
- [parent_view_ addSubview:[bar view]];
- NSRect frame = [[[bar view] superview] frame];
- frame.origin.y = 100;
- [[[bar view] superview] setFrame:frame];
-
- // Make sure it's on in a window so viewDidMoveToWindow is called
- NSView* contentView = [test_window() contentView];
- if (![parent_view_ isDescendantOf:contentView])
- [contentView addSubview:parent_view_];
-
- // Make sure it's open so certain things aren't no-ops.
- [bar updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- }
-};
-
-class BookmarkBarControllerTest : public BookmarkBarControllerTestBase {
- public:
- scoped_nsobject<BookmarkMenu> menu_;
- scoped_nsobject<NSMenuItem> menu_item_;
- scoped_nsobject<NSButtonCell> cell_;
- scoped_nsobject<BookmarkBarControllerNoOpen> bar_;
-
- BookmarkBarControllerTest() {
- bar_.reset(
- [[BookmarkBarControllerNoOpen alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth([parent_view_ frame])
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
-
- InstallAndToggleBar(bar_.get());
-
- // Create a menu/item to act like a sender
- menu_.reset([[BookmarkMenu alloc] initWithTitle:@"I_dont_care"]);
- menu_item_.reset([[NSMenuItem alloc]
- initWithTitle:@"still_dont_care"
- action:NULL
- keyEquivalent:@""]);
- cell_.reset([[NSButtonCell alloc] init]);
- [menu_item_ setMenu:menu_.get()];
- [menu_ setDelegate:cell_.get()];
- }
-
- // Return a menu item that points to the given URL.
- NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* node = model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("A title"), gurl);
- [menu_ setRepresentedObject:[NSNumber numberWithLongLong:node->id()]];
- return menu_item_;
- }
-
- // Does NOT take ownership of node.
- NSMenuItem* ItemForBookmarkBarMenu(const BookmarkNode* node) {
- [menu_ setRepresentedObject:[NSNumber numberWithLongLong:node->id()]];
- return menu_item_;
- }
-
- BookmarkBarControllerNoOpen* noOpenBar() {
- return (BookmarkBarControllerNoOpen*)bar_.get();
- }
-};
-
-TEST_F(BookmarkBarControllerTest, ShowWhenShowBookmarkBarTrue) {
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_TRUE([bar_ isInState:bookmarks::kShowingState]);
- EXPECT_FALSE([bar_ isInState:bookmarks::kDetachedState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- EXPECT_FALSE([[bar_ view] isHidden]);
- EXPECT_GT([resizeDelegate_ height], 0);
- EXPECT_GT([[bar_ view] frame].size.height, 0);
-}
-
-TEST_F(BookmarkBarControllerTest, HideWhenShowBookmarkBarFalse) {
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_FALSE([bar_ isInState:bookmarks::kShowingState]);
- EXPECT_FALSE([bar_ isInState:bookmarks::kDetachedState]);
- EXPECT_FALSE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- EXPECT_TRUE([[bar_ view] isHidden]);
- EXPECT_EQ(0, [resizeDelegate_ height]);
- EXPECT_EQ(0, [[bar_ view] frame].size.height);
-}
-
-TEST_F(BookmarkBarControllerTest, HideWhenShowBookmarkBarTrueButDisabled) {
- [bar_ setBookmarkBarEnabled:NO];
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_TRUE([bar_ isInState:bookmarks::kShowingState]);
- EXPECT_FALSE([bar_ isInState:bookmarks::kDetachedState]);
- EXPECT_FALSE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- EXPECT_TRUE([[bar_ view] isHidden]);
- EXPECT_EQ(0, [resizeDelegate_ height]);
- EXPECT_EQ(0, [[bar_ view] frame].size.height);
-}
-
-TEST_F(BookmarkBarControllerTest, ShowOnNewTabPage) {
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_FALSE([bar_ isInState:bookmarks::kShowingState]);
- EXPECT_TRUE([bar_ isInState:bookmarks::kDetachedState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- EXPECT_FALSE([[bar_ view] isHidden]);
- EXPECT_GT([resizeDelegate_ height], 0);
- EXPECT_GT([[bar_ view] frame].size.height, 0);
-
- // Make sure no buttons fall off the bar, either now or when resized
- // bigger or smaller.
- CGFloat sizes[] = { 300.0, -100.0, 200.0, -420.0 };
- CGFloat previousX = 0.0;
- for (unsigned x = 0; x < arraysize(sizes); x++) {
- // Confirm the buttons moved from the last check (which may be
- // init but that's fine).
- CGFloat newX = [[bar_ offTheSideButton] frame].origin.x;
- EXPECT_NE(previousX, newX);
- previousX = newX;
-
- // Confirm the buttons have a reasonable bounds. Recall that |-frame|
- // returns rectangles in the superview's coordinates.
- NSRect buttonViewFrame =
- [[bar_ buttonView] convertRect:[[bar_ buttonView] frame]
- fromView:[[bar_ buttonView] superview]];
- EXPECT_EQ([bar_ buttonView], [[bar_ offTheSideButton] superview]);
- EXPECT_TRUE(NSContainsRect(buttonViewFrame,
- [[bar_ offTheSideButton] frame]));
- EXPECT_EQ([bar_ buttonView], [[bar_ otherBookmarksButton] superview]);
- EXPECT_TRUE(NSContainsRect(buttonViewFrame,
- [[bar_ otherBookmarksButton] frame]));
-
- // Now move them implicitly.
- // We confirm FrameChangeNotification works in the next unit test;
- // we simply assume it works here to resize or reposition the
- // buttons above.
- NSRect frame = [[bar_ view] frame];
- frame.size.width += sizes[x];
- [[bar_ view] setFrame:frame];
- }
-}
-
-// Test whether |-updateAndShowNormalBar:...| sets states as we expect. Make
-// sure things don't crash.
-TEST_F(BookmarkBarControllerTest, StateChanges) {
- // First, go in one-at-a-time cycle.
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kHiddenState, [bar_ visualState]);
- EXPECT_FALSE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kShowingState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kShowingState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kDetachedState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
-
- // Now try some "jumps".
- for (int i = 0; i < 2; i++) {
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kHiddenState, [bar_ visualState]);
- EXPECT_FALSE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kShowingState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- }
-
- // Now try some "jumps".
- for (int i = 0; i < 2; i++) {
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kShowingState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_EQ(bookmarks::kDetachedState, [bar_ visualState]);
- EXPECT_TRUE([bar_ isVisible]);
- EXPECT_FALSE([bar_ isAnimationRunning]);
- }
-}
-
-// Make sure we're watching for frame change notifications.
-TEST_F(BookmarkBarControllerTest, FrameChangeNotification) {
- scoped_nsobject<BookmarkBarControllerTogglePong> bar;
- bar.reset(
- [[BookmarkBarControllerTogglePong alloc]
- initWithBrowser:helper_.browser()
- initialWidth:100 // arbitrary
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
- InstallAndToggleBar(bar.get());
-
- // Send a frame did change notification for the pong's view.
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSViewFrameDidChangeNotification
- object:[bar view]];
-
- EXPECT_GT([bar toggles], 0);
-}
-
-// Confirm our "no items" container goes away when we add the 1st
-// bookmark, and comes back when we delete the bookmark.
-TEST_F(BookmarkBarControllerTest, NoItemContainerGoesAway) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* bar = model->GetBookmarkBarNode();
-
- [bar_ loaded:model];
- BookmarkBarView* view = [bar_ buttonView];
- DCHECK(view);
- NSView* noItemContainer = [view noItemContainer];
- DCHECK(noItemContainer);
-
- EXPECT_FALSE([noItemContainer isHidden]);
- const BookmarkNode* node = model->AddURL(bar, bar->GetChildCount(),
- ASCIIToUTF16("title"),
- GURL("http://www.google.com"));
- EXPECT_TRUE([noItemContainer isHidden]);
- model->Remove(bar, bar->IndexOfChild(node));
- EXPECT_FALSE([noItemContainer isHidden]);
-
- // Now try it using a bookmark from the Other Bookmarks.
- const BookmarkNode* otherBookmarks = model->other_node();
- node = model->AddURL(otherBookmarks, otherBookmarks->GetChildCount(),
- ASCIIToUTF16("TheOther"),
- GURL("http://www.other.com"));
- EXPECT_FALSE([noItemContainer isHidden]);
- // Move it from Other Bookmarks to the bar.
- model->Move(node, bar, 0);
- EXPECT_TRUE([noItemContainer isHidden]);
- // Move it back to Other Bookmarks from the bar.
- model->Move(node, otherBookmarks, 0);
- EXPECT_FALSE([noItemContainer isHidden]);
-}
-
-// Confirm off the side button only enabled when reasonable.
-TEST_F(BookmarkBarControllerTest, OffTheSideButtonHidden) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ setIgnoreAnimations:YES];
-
- [bar_ loaded:model];
- EXPECT_TRUE([bar_ offTheSideButtonIsHidden]);
-
- for (int i = 0; i < 2; i++) {
- model->SetURLStarred(GURL("http://www.foo.com"), ASCIIToUTF16("small"),
- true);
- EXPECT_TRUE([bar_ offTheSideButtonIsHidden]);
- }
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- for (int i = 0; i < 20; i++) {
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("super duper wide title"),
- GURL("http://superfriends.hall-of-justice.edu"));
- }
- EXPECT_FALSE([bar_ offTheSideButtonIsHidden]);
-
- // Open the "off the side" and start deleting nodes. Make sure
- // deletion of the last node in "off the side" causes the folder to
- // close.
- EXPECT_FALSE([bar_ offTheSideButtonIsHidden]);
- NSButton* offTheSideButton = [bar_ offTheSideButton];
- // Open "off the side" menu.
- [bar_ openOffTheSideFolderFromButton:offTheSideButton];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- EXPECT_TRUE(bbfc);
- [bbfc setIgnoreAnimations:YES];
- while (parent->GetChildCount()) {
- // We've completed the job so we're done.
- if ([bar_ offTheSideButtonIsHidden])
- break;
- // Delete the last button.
- model->Remove(parent, parent->GetChildCount()-1);
- // If last one make sure the menu is closed and the button is hidden.
- // Else make sure menu stays open.
- if ([bar_ offTheSideButtonIsHidden]) {
- EXPECT_FALSE([bar_ folderController]);
- } else {
- EXPECT_TRUE([bar_ folderController]);
- }
- }
-}
-
-// http://crbug.com/46175 is a crash when deleting bookmarks from the
-// off-the-side menu while it is open. This test tries to bang hard
-// in this area to reproduce the crash.
-TEST_F(BookmarkBarControllerTest, DeleteFromOffTheSideWhileItIsOpen) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ setIgnoreAnimations:YES];
- [bar_ loaded:model];
-
- // Add a lot of bookmarks (per the bug).
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- for (int i = 0; i < 100; i++) {
- std::ostringstream title;
- title << "super duper wide title " << i;
- model->AddURL(parent, parent->GetChildCount(), ASCIIToUTF16(title.str()),
- GURL("http://superfriends.hall-of-justice.edu"));
- }
- EXPECT_FALSE([bar_ offTheSideButtonIsHidden]);
-
- // Open "off the side" menu.
- NSButton* offTheSideButton = [bar_ offTheSideButton];
- [bar_ openOffTheSideFolderFromButton:offTheSideButton];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- EXPECT_TRUE(bbfc);
- [bbfc setIgnoreAnimations:YES];
-
- // Start deleting items; try and delete randomish ones in case it
- // makes a difference.
- int indices[] = { 2, 4, 5, 1, 7, 9, 2, 0, 10, 9 };
- while (parent->GetChildCount()) {
- for (unsigned int i = 0; i < arraysize(indices); i++) {
- if (indices[i] < parent->GetChildCount()) {
- // First we mouse-enter the button to make things harder.
- NSArray* buttons = [bbfc buttons];
- for (BookmarkButton* button in buttons) {
- if ([button bookmarkNode] == parent->GetChild(indices[i])) {
- [bbfc mouseEnteredButton:button event:nil];
- break;
- }
- }
- // Then we remove the node. This triggers the button to get
- // deleted.
- model->Remove(parent, indices[i]);
- // Force visual update which is otherwise delayed.
- [[bbfc window] displayIfNeeded];
- }
- }
- }
-}
-
-// Test whether |-dragShouldLockBarVisibility| returns NO iff the bar is
-// detached.
-TEST_F(BookmarkBarControllerTest, TestDragShouldLockBarVisibility) {
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_TRUE([bar_ dragShouldLockBarVisibility]);
-
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- EXPECT_TRUE([bar_ dragShouldLockBarVisibility]);
-
- [bar_ updateAndShowNormalBar:YES
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_TRUE([bar_ dragShouldLockBarVisibility]);
-
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:YES
- withAnimation:NO];
- EXPECT_FALSE([bar_ dragShouldLockBarVisibility]);
-}
-
-TEST_F(BookmarkBarControllerTest, TagMap) {
- int64 ids[] = { 1, 3, 4, 40, 400, 4000, 800000000, 2, 123456789 };
- std::vector<int32> tags;
-
- // Generate some tags
- for (unsigned int i = 0; i < arraysize(ids); i++) {
- tags.push_back([bar_ menuTagFromNodeId:ids[i]]);
- }
-
- // Confirm reverse mapping.
- for (unsigned int i = 0; i < arraysize(ids); i++) {
- EXPECT_EQ(ids[i], [bar_ nodeIdFromMenuTag:tags[i]]);
- }
-
- // Confirm uniqueness.
- std::sort(tags.begin(), tags.end());
- for (unsigned int i=0; i<(tags.size()-1); i++) {
- EXPECT_NE(tags[i], tags[i+1]);
- }
-}
-
-TEST_F(BookmarkBarControllerTest, MenuForFolderNode) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- // First make sure something (e.g. "(empty)" string) is always present.
- NSMenu* menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
- EXPECT_GT([menu numberOfItems], 0);
-
- // Test two bookmarks.
- GURL gurl("http://www.foo.com");
- model->SetURLStarred(gurl, ASCIIToUTF16("small"), true);
- model->SetURLStarred(GURL("http://www.cnn.com"), ASCIIToUTF16("bigger title"),
- true);
- menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
- EXPECT_EQ([menu numberOfItems], 2);
- NSMenuItem *item = [menu itemWithTitle:@"bigger title"];
- EXPECT_TRUE(item);
- item = [menu itemWithTitle:@"small"];
- EXPECT_TRUE(item);
- if (item) {
- int64 tag = [bar_ nodeIdFromMenuTag:[item tag]];
- const BookmarkNode* node = model->GetNodeByID(tag);
- EXPECT_TRUE(node);
- EXPECT_EQ(gurl, node->GetURL());
- }
-
- // Test with an actual folder as well
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("f1"), GURL("http://framma-lamma.com"));
- model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("f2"), GURL("http://framma-lamma-ding-dong.com"));
- menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
- EXPECT_EQ([menu numberOfItems], 3);
-
- item = [menu itemWithTitle:@"group"];
- EXPECT_TRUE(item);
- EXPECT_TRUE([item hasSubmenu]);
- NSMenu *submenu = [item submenu];
- EXPECT_TRUE(submenu);
- EXPECT_EQ(2, [submenu numberOfItems]);
- EXPECT_TRUE([submenu itemWithTitle:@"f1"]);
- EXPECT_TRUE([submenu itemWithTitle:@"f2"]);
-}
-
-// Confirm openBookmark: forwards the request to the controller's delegate
-TEST_F(BookmarkBarControllerTest, OpenBookmark) {
- GURL gurl("http://walla.walla.ding.dong.com");
- scoped_ptr<BookmarkNode> node(new BookmarkNode(gurl));
-
- scoped_nsobject<BookmarkButtonCell> cell([[BookmarkButtonCell alloc] init]);
- [cell setBookmarkNode:node.get()];
- scoped_nsobject<BookmarkButton> button([[BookmarkButton alloc] init]);
- [button setCell:cell.get()];
- [cell setRepresentedObject:[NSValue valueWithPointer:node.get()]];
-
- [bar_ openBookmark:button];
- EXPECT_EQ(noOpenBar()->urls_[0], node->GetURL());
- EXPECT_EQ(noOpenBar()->dispositions_[0], CURRENT_TAB);
-}
-
-// Confirm opening of bookmarks works from the menus (different
-// dispositions than clicking on the button).
-TEST_F(BookmarkBarControllerTest, OpenBookmarkFromMenus) {
- const char* urls[] = { "http://walla.walla.ding.dong.com",
- "http://i_dont_know.com",
- "http://cee.enn.enn.dot.com" };
- SEL selectors[] = { @selector(openBookmarkInNewForegroundTab:),
- @selector(openBookmarkInNewWindow:),
- @selector(openBookmarkInIncognitoWindow:) };
- WindowOpenDisposition dispositions[] = { NEW_FOREGROUND_TAB,
- NEW_WINDOW,
- OFF_THE_RECORD };
- for (unsigned int i = 0; i < arraysize(dispositions); i++) {
- GURL gurl(urls[i]);
- [bar_ performSelector:selectors[i]
- withObject:ItemForBookmarkBarMenu(gurl)];
- EXPECT_EQ(noOpenBar()->urls_[0], gurl);
- EXPECT_EQ(noOpenBar()->dispositions_[0], dispositions[i]);
- [bar_ clear];
- }
-}
-
-TEST_F(BookmarkBarControllerTest, TestAddRemoveAndClear) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- NSView* buttonView = [bar_ buttonView];
- EXPECT_EQ(0U, [[bar_ buttons] count]);
- unsigned int initial_subview_count = [[buttonView subviews] count];
-
- // Make sure a redundant call doesn't choke
- [bar_ clearBookmarkBar];
- EXPECT_EQ(0U, [[bar_ buttons] count]);
- EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]);
-
- GURL gurl1("http://superfriends.hall-of-justice.edu");
- // Short titles increase the chances of this test succeeding if the view is
- // narrow.
- // TODO(viettrungluu): make the test independent of window/view size, font
- // metrics, button size and spacing, and everything else.
- string16 title1(ASCIIToUTF16("x"));
- model->SetURLStarred(gurl1, title1, true);
- EXPECT_EQ(1U, [[bar_ buttons] count]);
- EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]);
-
- GURL gurl2("http://legion-of-doom.gov");
- string16 title2(ASCIIToUTF16("y"));
- model->SetURLStarred(gurl2, title2, true);
- EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
-
- for (int i = 0; i < 3; i++) {
- // is_starred=false --> remove the bookmark
- model->SetURLStarred(gurl2, title2, false);
- EXPECT_EQ(1U, [[bar_ buttons] count]);
- EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]);
-
- // and bring it back
- model->SetURLStarred(gurl2, title2, true);
- EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
- }
-
- [bar_ clearBookmarkBar];
- EXPECT_EQ(0U, [[bar_ buttons] count]);
- EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]);
-
- // Explicit test of loaded: since this is a convenient spot
- [bar_ loaded:model];
- EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
-}
-
-// Make sure we don't create too many buttons; we only really need
-// ones that will be visible.
-TEST_F(BookmarkBarControllerTest, TestButtonLimits) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- EXPECT_EQ(0U, [[bar_ buttons] count]);
- // Add one; make sure we see it.
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://www.google.com"));
- EXPECT_EQ(1U, [[bar_ buttons] count]);
-
- // Add 30 which we expect to be 'too many'. Make sure we don't see
- // 30 buttons.
- model->Remove(parent, 0);
- EXPECT_EQ(0U, [[bar_ buttons] count]);
- for (int i=0; i<30; i++) {
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://www.google.com"));
- }
- int count = [[bar_ buttons] count];
- EXPECT_LT(count, 30L);
-
- // Add 10 more (to the front of the list so the on-screen buttons
- // would change) and make sure the count stays the same.
- for (int i=0; i<10; i++) {
- model->AddURL(parent, 0, /* index is 0, so front, not end */
- ASCIIToUTF16("title"), GURL("http://www.google.com"));
- }
-
- // Finally, grow the view and make sure the button count goes up.
- NSRect frame = [[bar_ view] frame];
- frame.size.width += 600;
- [[bar_ view] setFrame:frame];
- int finalcount = [[bar_ buttons] count];
- EXPECT_GT(finalcount, count);
-}
-
-// Make sure that each button we add marches to the right and does not
-// overlap with the previous one.
-TEST_F(BookmarkBarControllerTest, TestButtonMarch) {
- scoped_nsobject<NSMutableArray> cells([[NSMutableArray alloc] init]);
-
- CGFloat widths[] = { 10, 10, 100, 10, 500, 500, 80000, 60000, 1, 345 };
- for (unsigned int i = 0; i < arraysize(widths); i++) {
- NSCell* cell = [[CellWithDesiredSize alloc]
- initTextCell:@"foo"
- desiredSize:NSMakeSize(widths[i], 30)];
- [cells addObject:cell];
- [cell release];
- }
-
- int x_offset = 0;
- CGFloat x_end = x_offset; // end of the previous button
- for (unsigned int i = 0; i < arraysize(widths); i++) {
- NSRect r = [bar_ frameForBookmarkButtonFromCell:[cells objectAtIndex:i]
- xOffset:&x_offset];
- EXPECT_GE(r.origin.x, x_end);
- x_end = NSMaxX(r);
- }
-}
-
-TEST_F(BookmarkBarControllerTest, CheckForGrowth) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- GURL gurl1("http://www.google.com");
- string16 title1(ASCIIToUTF16("x"));
- model->SetURLStarred(gurl1, title1, true);
-
- GURL gurl2("http://www.google.com/blah");
- string16 title2(ASCIIToUTF16("y"));
- model->SetURLStarred(gurl2, title2, true);
-
- EXPECT_EQ(2U, [[bar_ buttons] count]);
- CGFloat width_1 = [[[bar_ buttons] objectAtIndex:0] frame].size.width;
- CGFloat x_2 = [[[bar_ buttons] objectAtIndex:1] frame].origin.x;
-
- NSButton* first = [[bar_ buttons] objectAtIndex:0];
- [[first cell] setTitle:@"This is a really big title; watch out mom!"];
- [bar_ checkForBookmarkButtonGrowth:first];
-
- // Make sure the 1st button is now wider, the 2nd one is moved over,
- // and they don't overlap.
- NSRect frame_1 = [[[bar_ buttons] objectAtIndex:0] frame];
- NSRect frame_2 = [[[bar_ buttons] objectAtIndex:1] frame];
- EXPECT_GT(frame_1.size.width, width_1);
- EXPECT_GT(frame_2.origin.x, x_2);
- EXPECT_GE(frame_2.origin.x, frame_1.origin.x + frame_1.size.width);
-}
-
-TEST_F(BookmarkBarControllerTest, DeleteBookmark) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- const char* urls[] = { "https://secret.url.com",
- "http://super.duper.web.site.for.doodz.gov",
- "http://www.foo-bar-baz.com/" };
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- for (unsigned int i = 0; i < arraysize(urls); i++) {
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("title"), GURL(urls[i]));
- }
- EXPECT_EQ(3, parent->GetChildCount());
- const BookmarkNode* middle_node = parent->GetChild(1);
-
- NSMenuItem* item = ItemForBookmarkBarMenu(middle_node);
- [bar_ deleteBookmark:item];
- EXPECT_EQ(2, parent->GetChildCount());
- EXPECT_EQ(parent->GetChild(0)->GetURL(), GURL(urls[0]));
- // node 2 moved into spot 1
- EXPECT_EQ(parent->GetChild(1)->GetURL(), GURL(urls[2]));
-}
-
-// TODO(jrg): write a test to confirm that nodeFavIconLoaded calls
-// checkForBookmarkButtonGrowth:.
-
-TEST_F(BookmarkBarControllerTest, Cell) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ loaded:model];
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("supertitle"),
- GURL("http://superfriends.hall-of-justice.edu"));
- const BookmarkNode* node = parent->GetChild(0);
-
- NSCell* cell = [bar_ cellForBookmarkNode:node];
- EXPECT_TRUE(cell);
- EXPECT_NSEQ(@"supertitle", [cell title]);
- EXPECT_EQ(node, [[cell representedObject] pointerValue]);
- EXPECT_TRUE([cell menu]);
-
- // Empty cells have no menu.
- cell = [bar_ cellForBookmarkNode:nil];
- EXPECT_FALSE([cell menu]);
- // Even empty cells have a title (of "(empty)")
- EXPECT_TRUE([cell title]);
-
- // cell is autoreleased; no need to release here
-}
-
-// Test drawing, mostly to ensure nothing leaks or crashes.
-TEST_F(BookmarkBarControllerTest, Display) {
- [[bar_ view] display];
-}
-
-// Test that middle clicking on a bookmark button results in an open action.
-TEST_F(BookmarkBarControllerTest, MiddleClick) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- GURL gurl1("http://www.google.com/");
- string16 title1(ASCIIToUTF16("x"));
- model->SetURLStarred(gurl1, title1, true);
-
- EXPECT_EQ(1U, [[bar_ buttons] count]);
- NSButton* first = [[bar_ buttons] objectAtIndex:0];
- EXPECT_TRUE(first);
-
- [first otherMouseUp:test_event_utils::MakeMouseEvent(NSOtherMouseUp, 0)];
- EXPECT_EQ(noOpenBar()->urls_.size(), 1U);
-}
-
-TEST_F(BookmarkBarControllerTest, DisplaysHelpMessageOnEmpty) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ loaded:model];
- EXPECT_FALSE([[[bar_ buttonView] noItemContainer] isHidden]);
-}
-
-TEST_F(BookmarkBarControllerTest, HidesHelpMessageWithBookmark) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://one.com"));
-
- [bar_ loaded:model];
- EXPECT_TRUE([[[bar_ buttonView] noItemContainer] isHidden]);
-}
-
-TEST_F(BookmarkBarControllerTest, BookmarkButtonSizing) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://one.com"));
-
- [bar_ loaded:model];
-
- // Make sure the internal bookmark button also is the correct height.
- NSArray* buttons = [bar_ buttons];
- EXPECT_GT([buttons count], 0u);
- for (NSButton* button in buttons) {
- EXPECT_FLOAT_EQ(
- (bookmarks::kBookmarkBarHeight + bookmarks::kVisualHeightOffset) - 2 *
- bookmarks::kBookmarkVerticalPadding,
- [button frame].size.height);
- }
-}
-
-TEST_F(BookmarkBarControllerTest, DropBookmarks) {
- const char* urls[] = {
- "http://qwantz.com",
- "http://xkcd.com",
- "javascript:alert('lolwut')",
- "file://localhost/tmp/local-file.txt" // As if dragged from the desktop.
- };
- const char* titles[] = {
- "Philosophoraptor",
- "Can't draw",
- "Inspiration",
- "Frum stuf"
- };
- EXPECT_EQ(arraysize(urls), arraysize(titles));
-
- NSMutableArray* nsurls = [NSMutableArray array];
- NSMutableArray* nstitles = [NSMutableArray array];
- for (size_t i = 0; i < arraysize(urls); ++i) {
- [nsurls addObject:base::SysUTF8ToNSString(urls[i])];
- [nstitles addObject:base::SysUTF8ToNSString(titles[i])];
- }
-
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- [bar_ addURLs:nsurls withTitles:nstitles at:NSZeroPoint];
- EXPECT_EQ(4, parent->GetChildCount());
- for (int i = 0; i < parent->GetChildCount(); ++i) {
- GURL gurl = parent->GetChild(i)->GetURL();
- if (gurl.scheme() == "http" ||
- gurl.scheme() == "javascript") {
- EXPECT_EQ(parent->GetChild(i)->GetURL(), GURL(urls[i]));
- } else {
- // Be flexible if the scheme needed to be added.
- std::string gurl_string = gurl.spec();
- std::string my_string = parent->GetChild(i)->GetURL().spec();
- EXPECT_NE(gurl_string.find(my_string), std::string::npos);
- }
- EXPECT_EQ(parent->GetChild(i)->GetTitle(), ASCIIToUTF16(titles[i]));
- }
-}
-
-TEST_F(BookmarkBarControllerTest, TestButtonOrBar) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- GURL gurl1("http://www.google.com");
- string16 title1(ASCIIToUTF16("x"));
- model->SetURLStarred(gurl1, title1, true);
-
- GURL gurl2("http://www.google.com/gurl_power");
- string16 title2(ASCIIToUTF16("gurl power"));
- model->SetURLStarred(gurl2, title2, true);
-
- NSButton* first = [[bar_ buttons] objectAtIndex:0];
- NSButton* second = [[bar_ buttons] objectAtIndex:1];
- EXPECT_TRUE(first && second);
-
- NSMenuItem* menuItem = [[[first cell] menu] itemAtIndex:0];
- const BookmarkNode* node = [bar_ nodeFromMenuItem:menuItem];
- EXPECT_TRUE(node);
- EXPECT_EQ(node, model->GetBookmarkBarNode()->GetChild(0));
-
- menuItem = [[[second cell] menu] itemAtIndex:0];
- node = [bar_ nodeFromMenuItem:menuItem];
- EXPECT_TRUE(node);
- EXPECT_EQ(node, model->GetBookmarkBarNode()->GetChild(1));
-
- menuItem = [[[bar_ view] menu] itemAtIndex:0];
- node = [bar_ nodeFromMenuItem:menuItem];
- EXPECT_TRUE(node);
- EXPECT_EQ(node, model->GetBookmarkBarNode());
-}
-
-TEST_F(BookmarkBarControllerTest, TestMenuNodeAndDisable) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- NSButton* button = [[bar_ buttons] objectAtIndex:0];
- EXPECT_TRUE(button);
-
- // Confirm the menu knows which node it is talking about
- BookmarkMenu* menu = static_cast<BookmarkMenu*>([[button cell] menu]);
- EXPECT_TRUE(menu);
- EXPECT_TRUE([menu isKindOfClass:[BookmarkMenu class]]);
- EXPECT_EQ(folder->id(), [menu id]);
-
- // Make sure "Open All" is disabled (nothing to open -- no children!)
- // (Assumes "Open All" is the 1st item)
- NSMenuItem* item = [menu itemAtIndex:0];
- EXPECT_FALSE([bar_ validateUserInterfaceItem:item]);
-
- // Now add a child and make sure the item would be enabled.
- model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("super duper wide title"),
- GURL("http://superfriends.hall-of-justice.edu"));
- EXPECT_TRUE([bar_ validateUserInterfaceItem:item]);
-}
-
-TEST_F(BookmarkBarControllerTest, TestDragButton) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- GURL gurls[] = { GURL("http://www.google.com/a"),
- GURL("http://www.google.com/b"),
- GURL("http://www.google.com/c") };
- string16 titles[] = { ASCIIToUTF16("a"),
- ASCIIToUTF16("b"),
- ASCIIToUTF16("c") };
- for (unsigned i = 0; i < arraysize(titles); i++) {
- model->SetURLStarred(gurls[i], titles[i], true);
- }
-
- EXPECT_EQ([[bar_ buttons] count], arraysize(titles));
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:0] title]);
-
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:2]
- to:NSMakePoint(0, 0)
- copy:NO];
- EXPECT_NSEQ(@"c", [[[bar_ buttons] objectAtIndex:0] title]);
- // Make sure a 'copy' did not happen.
- EXPECT_EQ([[bar_ buttons] count], arraysize(titles));
-
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:1]
- to:NSMakePoint(1000, 0)
- copy:NO];
- EXPECT_NSEQ(@"c", [[[bar_ buttons] objectAtIndex:0] title]);
- EXPECT_NSEQ(@"b", [[[bar_ buttons] objectAtIndex:1] title]);
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:2] title]);
- EXPECT_EQ([[bar_ buttons] count], arraysize(titles));
-
- // A drop of the 1st between the next 2.
- CGFloat x = NSMinX([[[bar_ buttons] objectAtIndex:2] frame]);
- x += [[bar_ view] frame].origin.x;
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:0]
- to:NSMakePoint(x, 0)
- copy:NO];
- EXPECT_NSEQ(@"b", [[[bar_ buttons] objectAtIndex:0] title]);
- EXPECT_NSEQ(@"c", [[[bar_ buttons] objectAtIndex:1] title]);
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:2] title]);
- EXPECT_EQ([[bar_ buttons] count], arraysize(titles));
-
- // A drop on a non-folder button. (Shouldn't try and go in it.)
- x = NSMidX([[[bar_ buttons] objectAtIndex:0] frame]);
- x += [[bar_ view] frame].origin.x;
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:2]
- to:NSMakePoint(x, 0)
- copy:NO];
- EXPECT_EQ(arraysize(titles), [[bar_ buttons] count]);
-
- // A drop on a folder button.
- const BookmarkNode* folder = model->AddGroup(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("awesome group"));
- DCHECK(folder);
- model->AddURL(folder, 0, ASCIIToUTF16("already"),
- GURL("http://www.google.com"));
- EXPECT_EQ(arraysize(titles) + 1, [[bar_ buttons] count]);
- EXPECT_EQ(1, folder->GetChildCount());
- x = NSMidX([[[bar_ buttons] objectAtIndex:0] frame]);
- x += [[bar_ view] frame].origin.x;
- string16 title = [[[bar_ buttons] objectAtIndex:2] bookmarkNode]->GetTitle();
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:2]
- to:NSMakePoint(x, 0)
- copy:NO];
- // Gone from the bar
- EXPECT_EQ(arraysize(titles), [[bar_ buttons] count]);
- // In the folder
- EXPECT_EQ(2, folder->GetChildCount());
- // At the end
- EXPECT_EQ(title, folder->GetChild(1)->GetTitle());
-}
-
-TEST_F(BookmarkBarControllerTest, TestCopyButton) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- GURL gurls[] = { GURL("http://www.google.com/a"),
- GURL("http://www.google.com/b"),
- GURL("http://www.google.com/c") };
- string16 titles[] = { ASCIIToUTF16("a"),
- ASCIIToUTF16("b"),
- ASCIIToUTF16("c") };
- for (unsigned i = 0; i < arraysize(titles); i++) {
- model->SetURLStarred(gurls[i], titles[i], true);
- }
- EXPECT_EQ([[bar_ buttons] count], arraysize(titles));
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:0] title]);
-
- // Drag 'a' between 'b' and 'c'.
- CGFloat x = NSMinX([[[bar_ buttons] objectAtIndex:2] frame]);
- x += [[bar_ view] frame].origin.x;
- [bar_ dragButton:[[bar_ buttons] objectAtIndex:0]
- to:NSMakePoint(x, 0)
- copy:YES];
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:0] title]);
- EXPECT_NSEQ(@"b", [[[bar_ buttons] objectAtIndex:1] title]);
- EXPECT_NSEQ(@"a", [[[bar_ buttons] objectAtIndex:2] title]);
- EXPECT_NSEQ(@"c", [[[bar_ buttons] objectAtIndex:3] title]);
- EXPECT_EQ([[bar_ buttons] count], 4U);
-}
-
-// Fake a theme with colored text. Apply it and make sure bookmark
-// buttons have the same colored text. Repeat more than once.
-TEST_F(BookmarkBarControllerTest, TestThemedButton) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- model->SetURLStarred(GURL("http://www.foo.com"), ASCIIToUTF16("small"), true);
- BookmarkButton* button = [[bar_ buttons] objectAtIndex:0];
- EXPECT_TRUE(button);
-
- NSArray* colors = [NSArray arrayWithObjects:[NSColor redColor],
- [NSColor blueColor],
- nil];
- for (NSColor* color in colors) {
- FakeTheme theme(color);
- [bar_ updateTheme:&theme];
- NSAttributedString* astr = [button attributedTitle];
- EXPECT_TRUE(astr);
- EXPECT_NSEQ(@"small", [astr string]);
- // Pick a char in the middle to test (index 3)
- NSDictionary* attributes = [astr attributesAtIndex:3 effectiveRange:NULL];
- NSColor* newColor =
- [attributes objectForKey:NSForegroundColorAttributeName];
- EXPECT_NSEQ(newColor, color);
- }
-}
-
-// Test that delegates and targets of buttons are cleared on dealloc.
-TEST_F(BookmarkBarControllerTest, TestClearOnDealloc) {
- // Make some bookmark buttons.
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- GURL gurls[] = { GURL("http://www.foo.com/"),
- GURL("http://www.bar.com/"),
- GURL("http://www.baz.com/") };
- string16 titles[] = { ASCIIToUTF16("a"),
- ASCIIToUTF16("b"),
- ASCIIToUTF16("c") };
- for (size_t i = 0; i < arraysize(titles); i++)
- model->SetURLStarred(gurls[i], titles[i], true);
-
- // Get and retain the buttons so we can examine them after dealloc.
- scoped_nsobject<NSArray> buttons([[bar_ buttons] retain]);
- EXPECT_EQ([buttons count], arraysize(titles));
-
- // Make sure that everything is set.
- for (BookmarkButton* button in buttons.get()) {
- ASSERT_TRUE([button isKindOfClass:[BookmarkButton class]]);
- EXPECT_TRUE([button delegate]);
- EXPECT_TRUE([button target]);
- EXPECT_TRUE([button action]);
- }
-
- // This will dealloc....
- bar_.reset();
-
- // Make sure that everything is cleared.
- for (BookmarkButton* button in buttons.get()) {
- EXPECT_FALSE([button delegate]);
- EXPECT_FALSE([button target]);
- EXPECT_FALSE([button action]);
- }
-}
-
-TEST_F(BookmarkBarControllerTest, TestFolders) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
- // Create some folder buttons.
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("f1"), GURL("http://framma-lamma.com"));
- folder = model->AddGroup(parent, parent->GetChildCount(),
- ASCIIToUTF16("empty"));
-
- EXPECT_EQ([[bar_ buttons] count], 2U);
-
- // First confirm mouseEntered does nothing if "menus" aren't active.
- NSEvent* event = test_event_utils::MakeMouseEvent(NSOtherMouseUp, 0);
- [bar_ mouseEnteredButton:[[bar_ buttons] objectAtIndex:0] event:event];
- EXPECT_FALSE([bar_ folderController]);
-
- // Make one active. Entering it is now a no-op.
- [bar_ openBookmarkFolderFromButton:[[bar_ buttons] objectAtIndex:0]];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- EXPECT_TRUE(bbfc);
- [bar_ mouseEnteredButton:[[bar_ buttons] objectAtIndex:0] event:event];
- EXPECT_EQ(bbfc, [bar_ folderController]);
-
- // Enter a different one; a new folderController is active.
- [bar_ mouseEnteredButton:[[bar_ buttons] objectAtIndex:1] event:event];
- EXPECT_NE(bbfc, [bar_ folderController]);
-
- // Confirm exited is a no-op.
- [bar_ mouseExitedButton:[[bar_ buttons] objectAtIndex:1] event:event];
- EXPECT_NE(bbfc, [bar_ folderController]);
-
- // Clean up.
- [bar_ closeBookmarkFolder:nil];
-}
-
-// Verify that the folder menu presentation properly tracks mouse movements
-// over the bar. Until there is a click no folder menus should show. After a
-// click on a folder folder menus should show until another click on a folder
-// button, and a click outside the bar and its folder menus.
-TEST_F(BookmarkBarControllerTest, TestFolderButtons) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b 4f:[ 4f1b 4f2b ] ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model and that we do not have a folder controller.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
- EXPECT_FALSE([bar_ folderController]);
-
- // Add a real bookmark so we can click on it.
- const BookmarkNode* folder = root->GetChild(3);
- model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("CLICK ME"),
- GURL("http://www.google.com/"));
-
- // Click on a folder button.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"4f"];
- EXPECT_TRUE(button);
- [bar_ openBookmarkFolderFromButton:button];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- EXPECT_TRUE(bbfc);
-
- // Make sure a 2nd click on the same button closes things.
- [bar_ openBookmarkFolderFromButton:button];
- EXPECT_FALSE([bar_ folderController]);
-
- // Next open is a different button.
- button = [bar_ buttonWithTitleEqualTo:@"2f"];
- EXPECT_TRUE(button);
- [bar_ openBookmarkFolderFromButton:button];
- EXPECT_TRUE([bar_ folderController]);
-
- // Mouse over a non-folder button and confirm controller has gone away.
- button = [bar_ buttonWithTitleEqualTo:@"1b"];
- EXPECT_TRUE(button);
- NSEvent* event = test_event_utils::MouseEventAtPoint([button center],
- NSMouseMoved, 0);
- [bar_ mouseEnteredButton:button event:event];
- EXPECT_FALSE([bar_ folderController]);
-
- // Mouse over the original folder and confirm a new controller.
- button = [bar_ buttonWithTitleEqualTo:@"2f"];
- EXPECT_TRUE(button);
- [bar_ mouseEnteredButton:button event:event];
- BookmarkBarFolderController* oldBBFC = [bar_ folderController];
- EXPECT_TRUE(oldBBFC);
-
- // 'Jump' over to a different folder and confirm a new controller.
- button = [bar_ buttonWithTitleEqualTo:@"4f"];
- EXPECT_TRUE(button);
- [bar_ mouseEnteredButton:button event:event];
- BookmarkBarFolderController* newBBFC = [bar_ folderController];
- EXPECT_TRUE(newBBFC);
- EXPECT_NE(oldBBFC, newBBFC);
-
- // A click on a real bookmark should close and stop tracking the folder menus.
- BookmarkButton* bookmarkButton = [newBBFC buttonWithTitleEqualTo:@"CLICK ME"];
- EXPECT_TRUE(bookmarkButton);
- [newBBFC openBookmark:bookmarkButton];
- EXPECT_FALSE([bar_ folderController]);
- [bar_ mouseEnteredButton:button event:event];
- EXPECT_FALSE([bar_ folderController]);
-}
-
-// Make sure the "off the side" folder looks like a bookmark folder
-// but only contains "off the side" items.
-TEST_F(BookmarkBarControllerTest, OffTheSideFolder) {
-
- // It starts hidden.
- EXPECT_TRUE([bar_ offTheSideButtonIsHidden]);
-
- // Create some buttons.
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- for (int x = 0; x < 30; x++) {
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("medium-size-title"),
- GURL("http://framma-lamma.com"));
- }
- // Add a couple more so we can delete one and make sure its button goes away.
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("DELETE_ME"), GURL("http://ashton-tate.com"));
- model->AddURL(parent, parent->GetChildCount(),
- ASCIIToUTF16("medium-size-title"),
- GURL("http://framma-lamma.com"));
-
- // Should no longer be hidden.
- EXPECT_FALSE([bar_ offTheSideButtonIsHidden]);
-
- // Open it; make sure we have a folder controller.
- EXPECT_FALSE([bar_ folderController]);
- [bar_ openOffTheSideFolderFromButton:[bar_ offTheSideButton]];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- EXPECT_TRUE(bbfc);
-
- // Confirm the contents are only buttons which fell off the side by
- // making sure that none of the nodes in the off-the-side folder are
- // found in bar buttons. Be careful since not all the bar buttons
- // may be currently displayed.
- NSArray* folderButtons = [bbfc buttons];
- NSArray* barButtons = [bar_ buttons];
- for (BookmarkButton* folderButton in folderButtons) {
- for (BookmarkButton* barButton in barButtons) {
- if ([barButton superview]) {
- EXPECT_NE([folderButton bookmarkNode], [barButton bookmarkNode]);
- }
- }
- }
-
- // Delete a bookmark in the off-the-side and verify it's gone.
- BookmarkButton* button = [bbfc buttonWithTitleEqualTo:@"DELETE_ME"];
- EXPECT_TRUE(button);
- model->Remove(parent, parent->GetChildCount() - 2);
- button = [bbfc buttonWithTitleEqualTo:@"DELETE_ME"];
- EXPECT_FALSE(button);
-}
-
-TEST_F(BookmarkBarControllerTest, EventToExitCheck) {
- NSEvent* event = test_event_utils::MakeMouseEvent(NSMouseMoved, 0);
- EXPECT_FALSE([bar_ isEventAnExitEvent:event]);
-
- BookmarkBarFolderWindow* folderWindow = [[[BookmarkBarFolderWindow alloc]
- init] autorelease];
- [[[bar_ view] window] addChildWindow:folderWindow
- ordered:NSWindowAbove];
- event = test_event_utils::LeftMouseDownAtPointInWindow(NSMakePoint(1,1),
- folderWindow);
- EXPECT_FALSE([bar_ isEventAnExitEvent:event]);
-
- event = test_event_utils::LeftMouseDownAtPointInWindow(NSMakePoint(100,100),
- test_window());
- EXPECT_TRUE([bar_ isEventAnExitEvent:event]);
-
- // Many components are arbitrary (e.g. location, keycode).
- event = [NSEvent keyEventWithType:NSKeyDown
- location:NSMakePoint(1,1)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- characters:@"x"
- charactersIgnoringModifiers:@"x"
- isARepeat:NO
- keyCode:87];
- EXPECT_TRUE([bar_ isEventAnExitEvent:event]);
-
- [[[bar_ view] window] removeChildWindow:folderWindow];
-}
-
-TEST_F(BookmarkBarControllerTest, DropDestination) {
- // Make some buttons.
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- model->AddGroup(parent, parent->GetChildCount(), ASCIIToUTF16("group 1"));
- model->AddGroup(parent, parent->GetChildCount(), ASCIIToUTF16("group 2"));
- EXPECT_EQ([[bar_ buttons] count], 2U);
-
- // Confirm "off to left" and "off to right" match nothing.
- NSPoint p = NSMakePoint(-1, 2);
- EXPECT_FALSE([bar_ buttonForDroppingOnAtPoint:p]);
- EXPECT_TRUE([bar_ shouldShowIndicatorShownForPoint:p]);
- p = NSMakePoint(50000, 10);
- EXPECT_FALSE([bar_ buttonForDroppingOnAtPoint:p]);
- EXPECT_TRUE([bar_ shouldShowIndicatorShownForPoint:p]);
-
- // Confirm "right in the center" (give or take a pixel) is a match,
- // and confirm "just barely in the button" is not. Anything more
- // specific seems likely to be tweaked.
- CGFloat viewFrameXOffset = [[bar_ view] frame].origin.x;
- for (BookmarkButton* button in [bar_ buttons]) {
- CGFloat x = NSMidX([button frame]) + viewFrameXOffset;
- // Somewhere near the center: a match
- EXPECT_EQ(button,
- [bar_ buttonForDroppingOnAtPoint:NSMakePoint(x-1, 10)]);
- EXPECT_EQ(button,
- [bar_ buttonForDroppingOnAtPoint:NSMakePoint(x+1, 10)]);
- EXPECT_FALSE([bar_ shouldShowIndicatorShownForPoint:NSMakePoint(x, 10)]);;
-
- // On the very edges: NOT a match
- x = NSMinX([button frame]) + viewFrameXOffset;
- EXPECT_NE(button,
- [bar_ buttonForDroppingOnAtPoint:NSMakePoint(x, 9)]);
- x = NSMaxX([button frame]) + viewFrameXOffset;
- EXPECT_NE(button,
- [bar_ buttonForDroppingOnAtPoint:NSMakePoint(x, 11)]);
- }
-}
-
-TEST_F(BookmarkBarControllerTest, NodeDeletedWhileMenuIsOpen) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ loaded:model];
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* initialNode = model->AddURL(
- parent, parent->GetChildCount(),
- ASCIIToUTF16("initial"),
- GURL("http://www.google.com"));
-
- NSMenuItem* item = ItemForBookmarkBarMenu(initialNode);
- EXPECT_EQ(0U, noOpenBar()->urls_.size());
-
- // Basic check of the menu item and an IBOutlet it can call.
- EXPECT_EQ(initialNode, [bar_ nodeFromMenuItem:item]);
- [bar_ openBookmarkInNewWindow:item];
- EXPECT_EQ(1U, noOpenBar()->urls_.size());
- [bar_ clear];
-
- // Now delete the node and make sure things are happy (no crash,
- // NULL node caught).
- model->Remove(parent, parent->IndexOfChild(initialNode));
- EXPECT_EQ(nil, [bar_ nodeFromMenuItem:item]);
- // Should not crash by referencing a deleted node.
- [bar_ openBookmarkInNewWindow:item];
- // Confirm the above did nothing in case it somehow didn't crash.
- EXPECT_EQ(0U, noOpenBar()->urls_.size());
-
- // Confirm some more non-crashes.
- [bar_ openBookmarkInNewForegroundTab:item];
- [bar_ openBookmarkInIncognitoWindow:item];
- [bar_ editBookmark:item];
- [bar_ copyBookmark:item];
- [bar_ deleteBookmark:item];
- [bar_ openAllBookmarks:item];
- [bar_ openAllBookmarksNewWindow:item];
- [bar_ openAllBookmarksIncognitoWindow:item];
-}
-
-TEST_F(BookmarkBarControllerTest, NodeDeletedWhileContextMenuIsOpen) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- [bar_ loaded:model];
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- const BookmarkNode* framma = model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("f1"),
- GURL("http://framma-lamma.com"));
-
- // Mock in a menu
- id origMenu = [bar_ buttonContextMenu];
- id fakeMenu = [OCMockObject partialMockForObject:origMenu];
- [[fakeMenu expect] cancelTracking];
- [bar_ setButtonContextMenu:fakeMenu];
-
- // Force a delete which should cancelTracking on the menu.
- model->Remove(framma->GetParent(), framma->GetParent()->IndexOfChild(framma));
-
- // Restore, then confirm cancelTracking was called.
- [bar_ setButtonContextMenu:origMenu];
- [fakeMenu verify];
-}
-
-TEST_F(BookmarkBarControllerTest, CloseFolderOnAnimate) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- model->AddGroup(parent, parent->GetChildCount(),
- ASCIIToUTF16("sibbling group"));
- model->AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("title a"),
- GURL("http://www.google.com/a"));
- model->AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("title super duper long long whoa momma title you betcha"),
- GURL("http://www.google.com/b"));
- BookmarkButton* button = [[bar_ buttons] objectAtIndex:0];
- EXPECT_FALSE([bar_ folderController]);
- [bar_ openBookmarkFolderFromButton:button];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- // The following tells us that the folder menu is showing. We want to make
- // sure the folder menu goes away if the bookmark bar is hidden.
- EXPECT_TRUE(bbfc);
- EXPECT_TRUE([bar_ isVisible]);
-
- // Hide the bookmark bar.
- [bar_ updateAndShowNormalBar:NO
- showDetachedBar:YES
- withAnimation:YES];
- EXPECT_TRUE([bar_ isAnimationRunning]);
-
- // Now that we've closed the bookmark bar (with animation) the folder menu
- // should have been closed thus releasing the folderController.
- EXPECT_FALSE([bar_ folderController]);
-}
-
-TEST_F(BookmarkBarControllerTest, MoveRemoveAddButtons) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Remember how many buttons are showing.
- int oldDisplayedButtons = [bar_ displayedButtonCount];
- NSArray* buttons = [bar_ buttons];
-
- // Move a button around a bit.
- [bar_ moveButtonFromIndex:0 toIndex:2];
- EXPECT_NSEQ(@"2f", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"1b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [bar_ displayedButtonCount]);
- [bar_ moveButtonFromIndex:2 toIndex:0];
- EXPECT_NSEQ(@"1b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [bar_ displayedButtonCount]);
-
- // Add a couple of buttons.
- const BookmarkNode* parent = root->GetChild(1); // Purloin an existing node.
- const BookmarkNode* node = parent->GetChild(0);
- [bar_ addButtonForNode:node atIndex:0];
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"1b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f", [[buttons objectAtIndex:2] title]);
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:3] title]);
- EXPECT_EQ(oldDisplayedButtons + 1, [bar_ displayedButtonCount]);
- node = parent->GetChild(1);
- [bar_ addButtonForNode:node atIndex:-1];
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"1b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f", [[buttons objectAtIndex:2] title]);
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:3] title]);
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:4] title]);
- EXPECT_EQ(oldDisplayedButtons + 2, [bar_ displayedButtonCount]);
-
- // Remove a couple of buttons.
- [bar_ removeButton:4 animate:NO];
- [bar_ removeButton:1 animate:NO];
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [bar_ displayedButtonCount]);
-}
-
-TEST_F(BookmarkBarControllerTest, ShrinkOrHideView) {
- NSRect viewFrame = NSMakeRect(0.0, 0.0, 500.0, 50.0);
- NSView* view = [[[NSView alloc] initWithFrame:viewFrame] autorelease];
- EXPECT_FALSE([view isHidden]);
- [bar_ shrinkOrHideView:view forMaxX:500.0];
- EXPECT_EQ(500.0, NSWidth([view frame]));
- EXPECT_FALSE([view isHidden]);
- [bar_ shrinkOrHideView:view forMaxX:450.0];
- EXPECT_EQ(450.0, NSWidth([view frame]));
- EXPECT_FALSE([view isHidden]);
- [bar_ shrinkOrHideView:view forMaxX:40.0];
- EXPECT_EQ(40.0, NSWidth([view frame]));
- EXPECT_FALSE([view isHidden]);
- [bar_ shrinkOrHideView:view forMaxX:31.0];
- EXPECT_EQ(31.0, NSWidth([view frame]));
- EXPECT_FALSE([view isHidden]);
- [bar_ shrinkOrHideView:view forMaxX:29.0];
- EXPECT_TRUE([view isHidden]);
-}
-
-class BookmarkBarControllerOpenAllTest : public BookmarkBarControllerTest {
-public:
- BookmarkBarControllerOpenAllTest() {
- resizeDelegate_.reset([[ViewResizerPong alloc] init]);
- NSRect parent_frame = NSMakeRect(0, 0, 800, 50);
- bar_.reset(
- [[BookmarkBarControllerOpenAllPong alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth(parent_frame)
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
- [bar_ view];
- // Awkwardness to look like we've been installed.
- [parent_view_ addSubview:[bar_ view]];
- NSRect frame = [[[bar_ view] superview] frame];
- frame.origin.y = 100;
- [[[bar_ view] superview] setFrame:frame];
-
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- parent_ = model->GetBookmarkBarNode();
- // { one, { two-one, two-two }, three }
- model->AddURL(parent_, parent_->GetChildCount(), ASCIIToUTF16("title"),
- GURL("http://one.com"));
- folder_ = model->AddGroup(parent_, parent_->GetChildCount(),
- ASCIIToUTF16("group"));
- model->AddURL(folder_, folder_->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://two-one.com"));
- model->AddURL(folder_, folder_->GetChildCount(),
- ASCIIToUTF16("title"), GURL("http://two-two.com"));
- model->AddURL(parent_, parent_->GetChildCount(),
- ASCIIToUTF16("title"), GURL("https://three.com"));
- }
- const BookmarkNode* parent_; // Weak
- const BookmarkNode* folder_; // Weak
-};
-
-TEST_F(BookmarkBarControllerOpenAllTest, OpenAllBookmarks) {
- // Our first OpenAll... is from the bar itself.
- [bar_ openAllBookmarks:ItemForBookmarkBarMenu(parent_)];
- BookmarkBarControllerOpenAllPong* specialBar =
- (BookmarkBarControllerOpenAllPong*)bar_.get();
- EXPECT_EQ([specialBar dispositionDetected], NEW_FOREGROUND_TAB);
-
- // Now try an OpenAll... from a folder node.
- [specialBar setDispositionDetected:IGNORE_ACTION]; // Reset
- [bar_ openAllBookmarks:ItemForBookmarkBarMenu(folder_)];
- EXPECT_EQ([specialBar dispositionDetected], NEW_FOREGROUND_TAB);
-}
-
-TEST_F(BookmarkBarControllerOpenAllTest, OpenAllNewWindow) {
- // Our first OpenAll... is from the bar itself.
- [bar_ openAllBookmarksNewWindow:ItemForBookmarkBarMenu(parent_)];
- BookmarkBarControllerOpenAllPong* specialBar =
- (BookmarkBarControllerOpenAllPong*)bar_.get();
- EXPECT_EQ([specialBar dispositionDetected], NEW_WINDOW);
-
- // Now try an OpenAll... from a folder node.
- [specialBar setDispositionDetected:IGNORE_ACTION]; // Reset
- [bar_ openAllBookmarksNewWindow:ItemForBookmarkBarMenu(folder_)];
- EXPECT_EQ([specialBar dispositionDetected], NEW_WINDOW);
-}
-
-TEST_F(BookmarkBarControllerOpenAllTest, OpenAllIncognito) {
- // Our first OpenAll... is from the bar itself.
- [bar_ openAllBookmarksIncognitoWindow:ItemForBookmarkBarMenu(parent_)];
- BookmarkBarControllerOpenAllPong* specialBar =
- (BookmarkBarControllerOpenAllPong*)bar_.get();
- EXPECT_EQ([specialBar dispositionDetected], OFF_THE_RECORD);
-
- // Now try an OpenAll... from a folder node.
- [specialBar setDispositionDetected:IGNORE_ACTION]; // Reset
- [bar_ openAllBookmarksIncognitoWindow:ItemForBookmarkBarMenu(folder_)];
- EXPECT_EQ([specialBar dispositionDetected], OFF_THE_RECORD);
-}
-
-// Command-click on a folder should open all the bookmarks in it.
-TEST_F(BookmarkBarControllerOpenAllTest, CommandClickOnFolder) {
- NSButton* first = [[bar_ buttons] objectAtIndex:0];
- EXPECT_TRUE(first);
-
- // Create the right kind of event; mock NSApp so [NSApp
- // currentEvent] finds it.
- NSEvent* commandClick = test_event_utils::MouseEventAtPoint(NSZeroPoint,
- NSLeftMouseDown,
- NSCommandKeyMask);
- id fakeApp = [OCMockObject partialMockForObject:NSApp];
- [[[fakeApp stub] andReturn:commandClick] currentEvent];
- id oldApp = NSApp;
- NSApp = fakeApp;
- size_t originalDispositionCount = noOpenBar()->dispositions_.size();
-
- // Click!
- [first performClick:first];
-
- size_t dispositionCount = noOpenBar()->dispositions_.size();
- EXPECT_EQ(originalDispositionCount+1, dispositionCount);
- EXPECT_EQ(noOpenBar()->dispositions_[dispositionCount-1], NEW_BACKGROUND_TAB);
-
- // Replace NSApp
- NSApp = oldApp;
-}
-
-class BookmarkBarControllerNotificationTest : public CocoaTest {
- public:
- BookmarkBarControllerNotificationTest() {
- resizeDelegate_.reset([[ViewResizerPong alloc] init]);
- NSRect parent_frame = NSMakeRect(0, 0, 800, 50);
- parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]);
- [parent_view_ setHidden:YES];
- bar_.reset(
- [[BookmarkBarControllerNotificationPong alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth(parent_frame)
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
-
- // Force loading of the nib.
- [bar_ view];
- // Awkwardness to look like we've been installed.
- [parent_view_ addSubview:[bar_ view]];
- NSRect frame = [[[bar_ view] superview] frame];
- frame.origin.y = 100;
- [[[bar_ view] superview] setFrame:frame];
-
- // Do not add the bar to a window, yet.
- }
-
- BrowserTestHelper helper_;
- scoped_nsobject<NSView> parent_view_;
- scoped_nsobject<ViewResizerPong> resizeDelegate_;
- scoped_nsobject<BookmarkBarControllerNotificationPong> bar_;
-};
-
-TEST_F(BookmarkBarControllerNotificationTest, DeregistersForNotifications) {
- NSWindow* window = [[CocoaTestHelperWindow alloc] init];
- [window setReleasedWhenClosed:YES];
-
- // First add the bookmark bar to the temp window, then to another window.
- [[window contentView] addSubview:parent_view_];
- [[test_window() contentView] addSubview:parent_view_];
-
- // Post a fake windowDidResignKey notification for the temp window and make
- // sure the bookmark bar controller wasn't listening.
- [[NSNotificationCenter defaultCenter]
- postNotificationName:NSWindowDidResignKeyNotification
- object:window];
- EXPECT_FALSE([bar_ windowDidResignKeyReceived]);
-
- // Close the temp window and make sure no notification was received.
- [window close];
- EXPECT_FALSE([bar_ windowWillCloseReceived]);
-}
-
-
-// TODO(jrg): draggingEntered: and draggingExited: trigger timers so
-// they are hard to test. Factor out "fire timers" into routines
-// which can be overridden to fire immediately to make behavior
-// confirmable.
-
-// TODO(jrg): add unit test to make sure "Other Bookmarks" responds
-// properly to a hover open.
-
-// TODO(viettrungluu): figure out how to test animations.
-
-class BookmarkBarControllerDragDropTest : public BookmarkBarControllerTestBase {
- public:
- scoped_nsobject<BookmarkBarControllerDragData> bar_;
-
- BookmarkBarControllerDragDropTest() {
- bar_.reset(
- [[BookmarkBarControllerDragData alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth([parent_view_ frame])
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
- InstallAndToggleBar(bar_.get());
- }
-};
-
-TEST_F(BookmarkBarControllerDragDropTest, DragMoveBarBookmarkToOffTheSide) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1bWithLongName 2fWithLongName:[ "
- "2f1bWithLongName 2f2fWithLongName:[ 2f2f1bWithLongName "
- "2f2f2bWithLongName 2f2f3bWithLongName 2f4b ] 2f3bWithLongName ] "
- "3bWithLongName 4bWithLongName 5bWithLongName 6bWithLongName "
- "7bWithLongName 8bWithLongName 9bWithLongName 10bWithLongName "
- "11bWithLongName 12bWithLongName 13b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Insure that the off-the-side is not showing.
- ASSERT_FALSE([bar_ offTheSideButtonIsHidden]);
-
- // Remember how many buttons are showing and are available.
- int oldDisplayedButtons = [bar_ displayedButtonCount];
- int oldChildCount = root->GetChildCount();
-
- // Pop up the off-the-side menu.
- BookmarkButton* otsButton = (BookmarkButton*)[bar_ offTheSideButton];
- ASSERT_TRUE(otsButton);
- [[otsButton target] performSelector:@selector(openOffTheSideFolderFromButton:)
- withObject:otsButton];
- BookmarkBarFolderController* otsController = [bar_ folderController];
- EXPECT_TRUE(otsController);
- NSWindow* toWindow = [otsController window];
- EXPECT_TRUE(toWindow);
- BookmarkButton* draggedButton =
- [bar_ buttonWithTitleEqualTo:@"3bWithLongName"];
- ASSERT_TRUE(draggedButton);
- int oldOTSCount = (int)[[otsController buttons] count];
- EXPECT_EQ(oldOTSCount, oldChildCount - oldDisplayedButtons);
- BookmarkButton* targetButton = [[otsController buttons] objectAtIndex:0];
- ASSERT_TRUE(targetButton);
- [otsController dragButton:draggedButton
- to:[targetButton center]
- copy:YES];
- // There should still be the same number of buttons in the bar
- // and off-the-side should have one more.
- int newDisplayedButtons = [bar_ displayedButtonCount];
- int newChildCount = root->GetChildCount();
- int newOTSCount = (int)[[otsController buttons] count];
- EXPECT_EQ(oldDisplayedButtons, newDisplayedButtons);
- EXPECT_EQ(oldChildCount + 1, newChildCount);
- EXPECT_EQ(oldOTSCount + 1, newOTSCount);
- EXPECT_EQ(newOTSCount, newChildCount - newDisplayedButtons);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, DragOffTheSideToOther) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1bWithLongName 2bWithLongName "
- "3bWithLongName 4bWithLongName 5bWithLongName 6bWithLongName "
- "7bWithLongName 8bWithLongName 9bWithLongName 10bWithLongName "
- "11bWithLongName 12bWithLongName 13bWithLongName 14bWithLongName "
- "15bWithLongName 16bWithLongName 17bWithLongName 18bWithLongName "
- "19bWithLongName 20bWithLongName ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- const BookmarkNode* other = model.other_node();
- const std::string other_string("1other 2other 3other ");
- model_test_utils::AddNodesFromModelString(model, other, other_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
- std::string actualOtherString = model_test_utils::ModelStringFromNode(other);
- EXPECT_EQ(other_string, actualOtherString);
-
- // Insure that the off-the-side is showing.
- ASSERT_FALSE([bar_ offTheSideButtonIsHidden]);
-
- // Remember how many buttons are showing and are available.
- int oldDisplayedButtons = [bar_ displayedButtonCount];
- int oldRootCount = root->GetChildCount();
- int oldOtherCount = other->GetChildCount();
-
- // Pop up the off-the-side menu.
- BookmarkButton* otsButton = (BookmarkButton*)[bar_ offTheSideButton];
- ASSERT_TRUE(otsButton);
- [[otsButton target] performSelector:@selector(openOffTheSideFolderFromButton:)
- withObject:otsButton];
- BookmarkBarFolderController* otsController = [bar_ folderController];
- EXPECT_TRUE(otsController);
- int oldOTSCount = (int)[[otsController buttons] count];
- EXPECT_EQ(oldOTSCount, oldRootCount - oldDisplayedButtons);
-
- // Pick an off-the-side button and drag it to the other bookmarks.
- BookmarkButton* draggedButton =
- [otsController buttonWithTitleEqualTo:@"20bWithLongName"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton = [bar_ otherBookmarksButton];
- ASSERT_TRUE(targetButton);
- [bar_ dragButton:draggedButton to:[targetButton center] copy:NO];
-
- // There should one less button in the bar, one less in off-the-side,
- // and one more in other bookmarks.
- int newRootCount = root->GetChildCount();
- int newOTSCount = (int)[[otsController buttons] count];
- int newOtherCount = other->GetChildCount();
- EXPECT_EQ(oldRootCount - 1, newRootCount);
- EXPECT_EQ(oldOTSCount - 1, newOTSCount);
- EXPECT_EQ(oldOtherCount + 1, newOtherCount);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkData) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
- const BookmarkNode* other = model.other_node();
- const std::string other_string("O1b O2b O3f:[ O3f1b O3f2f ] "
- "O4f:[ O4f1b O4f2f ] 05b ");
- model_test_utils::AddNodesFromModelString(model, other, other_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
- actual = model_test_utils::ModelStringFromNode(other);
- EXPECT_EQ(other_string, actual);
-
- // Remember the little ones.
- int oldChildCount = root->GetChildCount();
-
- BookmarkButton* targetButton = [bar_ buttonWithTitleEqualTo:@"3b"];
- ASSERT_TRUE(targetButton);
-
- // Gen up some dragging data.
- const BookmarkNode* newNode = other->GetChild(2);
- [bar_ setDragDataNode:newNode];
- scoped_nsobject<FakeDragInfo> dragInfo([[FakeDragInfo alloc] init]);
- [dragInfo setDropLocation:[targetButton center]];
- [bar_ dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()];
-
- // There should one more button in the bar.
- int newChildCount = root->GetChildCount();
- EXPECT_EQ(oldChildCount + 1, newChildCount);
- // Verify the model.
- const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] O3f:[ O3f1b O3f2f ] 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
- oldChildCount = newChildCount;
-
- // Now do it over a folder button.
- targetButton = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(targetButton);
- NSPoint targetPoint = [targetButton center];
- newNode = other->GetChild(2); // Should be O4f.
- EXPECT_EQ(newNode->GetTitle(), ASCIIToUTF16("O4f"));
- [bar_ setDragDataNode:newNode];
- [dragInfo setDropLocation:targetPoint];
- [bar_ dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()];
-
- newChildCount = root->GetChildCount();
- EXPECT_EQ(oldChildCount, newChildCount);
- // Verify the model.
- const std::string expected1("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b O4f:[ O4f1b O4f2f ] ] O3f:[ O3f1b O3f2f ] "
- "3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected1, actual);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, AddURLs) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
-
- // Remember the children.
- int oldChildCount = root->GetChildCount();
-
- BookmarkButton* targetButton = [bar_ buttonWithTitleEqualTo:@"3b"];
- ASSERT_TRUE(targetButton);
-
- NSArray* urls = [NSArray arrayWithObjects: @"http://www.a.com/",
- @"http://www.b.com/", nil];
- NSArray* titles = [NSArray arrayWithObjects: @"SiteA", @"SiteB", nil];
- [bar_ addURLs:urls withTitles:titles at:[targetButton center]];
-
- // There should two more nodes in the bar.
- int newChildCount = root->GetChildCount();
- EXPECT_EQ(oldChildCount + 2, newChildCount);
- // Verify the model.
- const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] SiteA SiteB 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, ControllerForNode) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Find the main bar controller.
- const void* expectedController = bar_;
- const void* actualController = [bar_ controllerForNode:root];
- EXPECT_EQ(expectedController, actualController);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, DropPositionIndicator) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b 2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModel = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModel);
-
- // Test a series of points starting at the right edge of the bar.
- BookmarkButton* targetButton = [bar_ buttonWithTitleEqualTo:@"1b"];
- ASSERT_TRUE(targetButton);
- NSPoint targetPoint = [targetButton left];
- const CGFloat xDelta = 0.5 * bookmarks::kBookmarkHorizontalPadding;
- const CGFloat baseOffset = targetPoint.x;
- CGFloat expected = xDelta;
- CGFloat actual = [bar_ indicatorPosForDragToPoint:targetPoint];
- EXPECT_CGFLOAT_EQ(expected, actual);
- targetButton = [bar_ buttonWithTitleEqualTo:@"2f"];
- actual = [bar_ indicatorPosForDragToPoint:[targetButton right]];
- targetButton = [bar_ buttonWithTitleEqualTo:@"3b"];
- expected = [targetButton left].x - baseOffset + xDelta;
- EXPECT_CGFLOAT_EQ(expected, actual);
- targetButton = [bar_ buttonWithTitleEqualTo:@"4b"];
- targetPoint = [targetButton right];
- targetPoint.x += 100; // Somewhere off to the right.
- expected = NSMaxX([targetButton frame]) + xDelta;
- actual = [bar_ indicatorPosForDragToPoint:targetPoint];
- EXPECT_CGFLOAT_EQ(expected, actual);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, PulseButton) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* root = model->GetBookmarkBarNode();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(root, root->GetChildCount(),
- ASCIIToUTF16("title"), gurl);
-
- BookmarkButton* button = [[bar_ buttons] objectAtIndex:0];
- EXPECT_FALSE([button isContinuousPulsing]);
-
- NSValue *value = [NSValue valueWithPointer:node];
- NSDictionary *dict = [NSDictionary
- dictionaryWithObjectsAndKeys:value,
- bookmark_button::kBookmarkKey,
- [NSNumber numberWithBool:YES],
- bookmark_button::kBookmarkPulseFlagKey,
- nil];
- [[NSNotificationCenter defaultCenter]
- postNotificationName:bookmark_button::kPulseBookmarkButtonNotification
- object:nil
- userInfo:dict];
- EXPECT_TRUE([button isContinuousPulsing]);
-
- dict = [NSDictionary dictionaryWithObjectsAndKeys:value,
- bookmark_button::kBookmarkKey,
- [NSNumber numberWithBool:NO],
- bookmark_button::kBookmarkPulseFlagKey,
- nil];
- [[NSNotificationCenter defaultCenter]
- postNotificationName:bookmark_button::kPulseBookmarkButtonNotification
- object:nil
- userInfo:dict];
- EXPECT_FALSE([button isContinuousPulsing]);
-}
-
-TEST_F(BookmarkBarControllerDragDropTest, DragBookmarkDataToTrash) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
-
- int oldChildCount = root->GetChildCount();
-
- // Drag a button to the trash.
- BookmarkButton* buttonToDelete = [bar_ buttonWithTitleEqualTo:@"3b"];
- ASSERT_TRUE(buttonToDelete);
- EXPECT_TRUE([bar_ canDragBookmarkButtonToTrash:buttonToDelete]);
- [bar_ didDragBookmarkToTrash:buttonToDelete];
-
- // There should be one less button in the bar.
- int newChildCount = root->GetChildCount();
- EXPECT_EQ(oldChildCount - 1, newChildCount);
- // Verify the model.
- const std::string expected("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
-
- // Verify that the other bookmark folder can't be deleted.
- BookmarkButton *otherButton = [bar_ otherBookmarksButton];
- EXPECT_FALSE([bar_ canDragBookmarkButtonToTrash:otherButton]);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h
deleted file mode 100644
index c8eaf71..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_BUTTON_CELL_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_BUTTON_CELL_H_
-#pragma once
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-
-class BookmarkNode;
-
-// A button cell that handles drawing/highlighting of buttons in the
-// bookmark bar. This cell forwards mouseEntered/mouseExited events
-// to its control view so that pseudo-menu operations
-// (e.g. hover-over to open) can be implemented.
-@interface BookmarkBarFolderButtonCell : BookmarkButtonCell {
- @private
- scoped_nsobject<NSColor> frameColor_;
-}
-
-// Create a button cell which draws without a theme and with a frame
-// color provided by the BrowserThemeProvider defaults.
-+ (id)buttonCellForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_BUTTON_CELL_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm
deleted file mode 100644
index a3a73a3..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.mm
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
-
-@implementation BookmarkBarFolderButtonCell
-
-+ (id)buttonCellForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage {
- id buttonCell =
- [[[BookmarkBarFolderButtonCell alloc] initForNode:node
- contextMenu:contextMenu
- cellText:cellText
- cellImage:cellImage]
- autorelease];
- return buttonCell;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm
deleted file mode 100644
index 0fb8ae3..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell_unittest.mm
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-
-namespace {
-
-class BookmarkBarFolderButtonCellTest : public CocoaTest {
-};
-
-// Basic creation.
-TEST_F(BookmarkBarFolderButtonCellTest, Create) {
- scoped_nsobject<BookmarkBarFolderButtonCell> cell;
- cell.reset([[BookmarkBarFolderButtonCell buttonCellForNode:nil
- contextMenu:nil
- cellText:nil
- cellImage:nil] retain]);
- EXPECT_TRUE(cell);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h
deleted file mode 100644
index 1511f11..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-
-@class BookmarkBarController;
-@class BookmarkBarFolderView;
-@class BookmarkFolderTarget;
-@class BookmarkBarFolderHoverState;
-
-// A controller for the pop-up windows from bookmark folder buttons
-// which look sort of like menus.
-@interface BookmarkBarFolderController :
- NSWindowController<BookmarkButtonDelegate,
- BookmarkButtonControllerProtocol> {
- @private
- // The button whose click opened us.
- scoped_nsobject<BookmarkButton> parentButton_;
-
- // Bookmark bar folder controller chains are torn down in two ways:
- // 1. Clicking "outside" the folder (see use of
- // CrApplicationEventHookProtocol in the bookmark bar controller).
- // 2. Engaging a different folder (via hover over or explicit click).
- //
- // In either case, the BookmarkButtonControllerProtocol method
- // closeAllBookmarkFolders gets called. For bookmark bar folder
- // controllers, this is passed up the chain so we begin with a top
- // level "close".
- // When any bookmark folder window closes, it necessarily tells
- // subcontroller windows to close (down the chain), and autoreleases
- // the controller. (Must autorelease since the controller can still
- // get delegate events such as windowDidClose).
- //
- // Bookmark bar folder controllers own their buttons. When doing
- // drag and drop of a button from one sub-sub-folder to a different
- // sub-sub-folder, we need to make sure the button's pointers stay
- // valid until we've dropped (or cancelled). Note that such a drag
- // causes the source sub-sub-folder (previous parent window) to go
- // away (windows close, controllers autoreleased) since you're
- // hovering over a different folder chain for dropping. To keep
- // things valid (like the button's target, its delegate, the parent
- // cotroller that we have a pointer to below [below], etc), we heep
- // strong pointers to our owning controller, so the entire chain
- // stays owned.
-
- // Our parent controller, if we are a nested folder, otherwise nil.
- // Strong to insure the object lives as long as we need it.
- scoped_nsobject<BookmarkBarFolderController> parentController_;
-
- // The main bar controller from whence we or a parent sprang.
- BookmarkBarController* barController_; // WEAK: It owns us.
-
- // Our buttons. We do not have buttons for nested folders.
- scoped_nsobject<NSMutableArray> buttons_;
-
- // The scroll view that contains our main button view (below).
- IBOutlet NSScrollView* scrollView_;
-
- // Are we scrollable? If no, the full contents of the folder are
- // always visible.
- BOOL scrollable_;
-
- BOOL scrollUpArrowShown_;
- BOOL scrollDownArrowShown_;
-
- // YES if subfolders should grow to the right (the default).
- // Direction switches if we'd grow off the screen.
- BOOL subFolderGrowthToRight_;
-
- // The main view of this window (where the buttons go).
- IBOutlet BookmarkBarFolderView* mainView_;
-
- // Weak; we keep track to work around a
- // setShowsBorderOnlyWhileMouseInside bug.
- BookmarkButton* buttonThatMouseIsIn_;
-
- // The context menu for a bookmark button which represents an URL.
- IBOutlet NSMenu* buttonMenu_;
-
- // The context menu for a bookmark button which represents a folder.
- IBOutlet NSMenu* folderMenu_;
-
- // We model hover state as a state machine with specific allowable
- // transitions. |hoverState_| is the state of this machine at any
- // given time.
- scoped_nsobject<BookmarkBarFolderHoverState> hoverState_;
-
- // Logic for dealing with a click on a bookmark folder button.
- scoped_nsobject<BookmarkFolderTarget> folderTarget_;
-
- // A controller for a pop-up bookmark folder window (custom menu).
- // We (self) are the parentController_ for our folderController_.
- // This is not a scoped_nsobject because it owns itself (when its
- // window closes the controller gets autoreleased).
- BookmarkBarFolderController* folderController_;
-
- // Implement basic menu scrolling through this tracking area.
- scoped_nsobject<NSTrackingArea> scrollTrackingArea_;
-
- // Timer to continue scrolling as needed. We own the timer but
- // don't release it when done (we invalidate it).
- NSTimer* scrollTimer_;
-
- // Amount to scroll by on each timer fire. Can be + or -.
- CGFloat verticalScrollDelta_;
-
- // We need to know the size of the vertical scrolling arrows so we
- // can obscure/unobscure them.
- CGFloat verticalScrollArrowHeight_;
-
- // Set to YES to prevent any node animations. Useful for unit testing so that
- // incomplete animations do not cause valgrind complaints.
- BOOL ignoreAnimations_;
-}
-
-// Designated initializer.
-- (id)initWithParentButton:(BookmarkButton*)button
- parentController:(BookmarkBarFolderController*)parentController
- barController:(BookmarkBarController*)barController;
-
-// Return the parent button that owns the bookmark folder we represent.
-- (BookmarkButton*)parentButton;
-
-// Offset our folder menu window. This is usually needed in response to a
-// parent folder menu window or the bookmark bar changing position due to
-// the dragging of a bookmark node from the parent into this folder menu.
-- (void)offsetFolderMenuWindow:(NSSize)offset;
-
-// Re-layout the window menu in case some buttons were added or removed,
-// specifically as a result of the bookmark bar changing configuration
-// and altering the contents of the off-the-side folder.
-- (void)reconfigureMenu;
-
-// Actions from a context menu over a button or folder.
-- (IBAction)cutBookmark:(id)sender;
-- (IBAction)copyBookmark:(id)sender;
-- (IBAction)pasteBookmark:(id)sender;
-- (IBAction)deleteBookmark:(id)sender;
-
-// Passed up by a child view to tell us of a desire to scroll.
-- (void)scrollWheel:(NSEvent *)theEvent;
-
-// Forwarded to the associated BookmarkBarController.
-- (IBAction)addFolder:(id)sender;
-- (IBAction)addPage:(id)sender;
-- (IBAction)editBookmark:(id)sender;
-- (IBAction)openBookmark:(id)sender;
-- (IBAction)openAllBookmarks:(id)sender;
-- (IBAction)openAllBookmarksIncognitoWindow:(id)sender;
-- (IBAction)openAllBookmarksNewWindow:(id)sender;
-- (IBAction)openBookmarkInIncognitoWindow:(id)sender;
-- (IBAction)openBookmarkInNewForegroundTab:(id)sender;
-- (IBAction)openBookmarkInNewWindow:(id)sender;
-
-@property (assign, nonatomic) BOOL subFolderGrowthToRight;
-
-@end
-
-@interface BookmarkBarFolderController(TestingAPI)
-- (NSView*)mainView;
-- (NSPoint)windowTopLeftForWidth:(int)windowWidth;
-- (NSArray*)buttons;
-- (BookmarkBarFolderController*)folderController;
-- (id)folderTarget;
-- (void)configureWindowLevel;
-- (void)performOneScroll:(CGFloat)delta;
-- (BookmarkButton*)buttonThatMouseIsIn;
-// Set to YES in order to prevent animations.
-- (void)setIgnoreAnimations:(BOOL)ignore;
-
-// Return YES if we can scroll up or down.
-- (BOOL)canScrollUp;
-- (BOOL)canScrollDown;
-// Return YES if the scrollable_ flag has been set.
-- (BOOL)scrollable;
-
-- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point;
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm
deleted file mode 100644
index 55fa2d0..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm
+++ /dev/null
@@ -1,1459 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-
-#include "base/mac_util.h"
-#include "base/nsimage_cache_mac.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_utils.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/event_utils.h"
-#import "chrome/browser/themes/browser_theme_provider.h"
-
-namespace {
-
-// Frequency of the scrolling timer in seconds.
-const NSTimeInterval kBookmarkBarFolderScrollInterval = 0.1;
-
-// Amount to scroll by per timer fire. We scroll rather slowly; to
-// accomodate we do several at a time.
-const CGFloat kBookmarkBarFolderScrollAmount =
- 3 * bookmarks::kBookmarkButtonVerticalSpan;
-
-// Amount to scroll for each scroll wheel delta.
-const CGFloat kBookmarkBarFolderScrollWheelAmount =
- 1 * bookmarks::kBookmarkButtonVerticalSpan;
-
-// When constraining a scrolling bookmark bar folder window to the
-// screen, shrink the "constrain" by this much vertically. Currently
-// this is 0.0 to avoid a problem with tracking areas leaving the
-// window, but should probably be 8.0 or something.
-// TODO(jrg): http://crbug.com/36225
-const CGFloat kScrollWindowVerticalMargin = 0.0;
-
-} // namespace
-
-@interface BookmarkBarFolderController(Private)
-- (void)configureWindow;
-- (void)addOrUpdateScrollTracking;
-- (void)removeScrollTracking;
-- (void)endScroll;
-- (void)addScrollTimerWithDelta:(CGFloat)delta;
-
-// Determine the best button width (which will be the widest button or the
-// maximum allowable button width, whichever is less) and resize all buttons.
-// Return the new width (so that the window can be adjusted, if necessary).
-- (CGFloat)adjustButtonWidths;
-
-// Returns the total menu height needed to display |buttonCount| buttons.
-// Does not do any fancy tricks like trimming the height to fit on the screen.
-- (int)windowHeightForButtonCount:(int)buttonCount;
-
-// Adjust the height and horizontal position of the window such that the
-// scroll arrows are shown as needed and the window appears completely
-// on screen.
-- (void)adjustWindowForHeight:(int)windowHeight;
-
-// Show or hide the scroll arrows at the top/bottom of the window.
-- (void)showOrHideScrollArrows;
-
-// |point| is in the base coordinate system of the destination window;
-// it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be
-// made and inserted into the new location while leaving the bookmark in
-// the old location, otherwise move the bookmark by removing from its old
-// location and inserting into the new location.
-- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
- to:(NSPoint)point
- copy:(BOOL)copy;
-
-@end
-
-@interface BookmarkButton (BookmarkBarFolderMenuHighlighting)
-
-// Make the button's border frame always appear when |forceOn| is YES,
-// otherwise only border the button when the mouse is inside the button.
-- (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn;
-
-// On 10.6 event dispatch for an NSButtonCell's
-// showsBorderOnlyWhileMouseInside seems broken if scrolling the
-// view that contains the button. It appears that a mouseExited:
-// gets lost, so the button stays highlit forever. We accomodate
-// here.
-- (void)toggleButtonBorderingWhileMouseInside;
-@end
-
-@implementation BookmarkButton (BookmarkBarFolderMenuHighlighting)
-
-- (void)forceButtonBorderToStayOnAlways:(BOOL)forceOn {
- [self setShowsBorderOnlyWhileMouseInside:!forceOn];
- [self setNeedsDisplay];
-}
-
-- (void)toggleButtonBorderingWhileMouseInside {
- BOOL toggle = [self showsBorderOnlyWhileMouseInside];
- [self setShowsBorderOnlyWhileMouseInside:!toggle];
- [self setShowsBorderOnlyWhileMouseInside:toggle];
-}
-
-@end
-
-@implementation BookmarkBarFolderController
-
-@synthesize subFolderGrowthToRight = subFolderGrowthToRight_;
-
-- (id)initWithParentButton:(BookmarkButton*)button
- parentController:(BookmarkBarFolderController*)parentController
- barController:(BookmarkBarController*)barController {
- NSString* nibPath =
- [mac_util::MainAppBundle() pathForResource:@"BookmarkBarFolderWindow"
- ofType:@"nib"];
- if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
- parentButton_.reset([button retain]);
-
- // We want the button to remain bordered as part of the menu path.
- [button forceButtonBorderToStayOnAlways:YES];
-
- parentController_.reset([parentController retain]);
- if (!parentController_)
- [self setSubFolderGrowthToRight:YES];
- else
- [self setSubFolderGrowthToRight:[parentController
- subFolderGrowthToRight]];
- barController_ = barController; // WEAK
- buttons_.reset([[NSMutableArray alloc] init]);
- folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]);
- NSImage* image = nsimage_cache::ImageNamed(@"menu_overflow_up.pdf");
- DCHECK(image);
- verticalScrollArrowHeight_ = [image size].height;
- [self configureWindow];
- hoverState_.reset([[BookmarkBarFolderHoverState alloc] init]);
- }
- return self;
-}
-
-- (void)dealloc {
- // The button is no longer part of the menu path.
- [parentButton_ forceButtonBorderToStayOnAlways:NO];
- [parentButton_ setNeedsDisplay];
-
- [self removeScrollTracking];
- [self endScroll];
- [hoverState_ draggingExited];
-
- // Delegate pattern does not retain; make sure pointers to us are removed.
- for (BookmarkButton* button in buttons_.get()) {
- [button setDelegate:nil];
- [button setTarget:nil];
- [button setAction:nil];
- }
-
- // Note: we don't need to
- // [NSObject cancelPreviousPerformRequestsWithTarget:self];
- // Because all of our performSelector: calls use withDelay: which
- // retains us.
- [super dealloc];
-}
-
-// Overriden from NSWindowController to call childFolderWillShow: before showing
-// the window.
-- (void)showWindow:(id)sender {
- [barController_ childFolderWillShow:self];
- [super showWindow:sender];
-}
-
-- (BookmarkButton*)parentButton {
- return parentButton_.get();
-}
-
-- (void)offsetFolderMenuWindow:(NSSize)offset {
- NSWindow* window = [self window];
- NSRect windowFrame = [window frame];
- windowFrame.origin.x -= offset.width;
- windowFrame.origin.y += offset.height; // Yes, in the opposite direction!
- [window setFrame:windowFrame display:YES];
- [folderController_ offsetFolderMenuWindow:offset];
-}
-
-- (void)reconfigureMenu {
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
- for (BookmarkButton* button in buttons_.get()) {
- [button setDelegate:nil];
- [button removeFromSuperview];
- }
- [buttons_ removeAllObjects];
- [self configureWindow];
-}
-
-#pragma mark Private Methods
-
-- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)child {
- NSImage* image = child ? [barController_ favIconForNode:child] : nil;
- NSMenu* menu = child ? child->is_folder() ? folderMenu_ : buttonMenu_ : nil;
- BookmarkBarFolderButtonCell* cell =
- [BookmarkBarFolderButtonCell buttonCellForNode:child
- contextMenu:menu
- cellText:nil
- cellImage:image];
- [cell setTag:kStandardButtonTypeWithLimitedClickFeedback];
- return cell;
-}
-
-// Redirect to our logic shared with BookmarkBarController.
-- (IBAction)openBookmarkFolderFromButton:(id)sender {
- [folderTarget_ openBookmarkFolderFromButton:sender];
-}
-
-// Create a bookmark button for the given node using frame.
-//
-// If |node| is NULL this is an "(empty)" button.
-// Does NOT add this button to our button list.
-// Returns an autoreleased button.
-// Adjusts the input frame width as appropriate.
-//
-// TODO(jrg): combine with addNodesToButtonList: code from
-// bookmark_bar_controller.mm, and generalize that to use both x and y
-// offsets.
-// http://crbug.com/35966
-- (BookmarkButton*)makeButtonForNode:(const BookmarkNode*)node
- frame:(NSRect)frame {
- BookmarkButtonCell* cell = [self cellForBookmarkNode:node];
- DCHECK(cell);
-
- // We must decide if we draw the folder arrow before we ask the cell
- // how big it needs to be.
- if (node && node->is_folder()) {
- // Warning when combining code with bookmark_bar_controller.mm:
- // this call should NOT be made for the bar buttons; only for the
- // subfolder buttons.
- [cell setDrawFolderArrow:YES];
- }
-
- // The "+2" is needed because, sometimes, Cocoa is off by a tad when
- // returning the value it thinks it needs.
- CGFloat desired = [cell cellSize].width + 2;
- // The width is determined from the maximum of the proposed width
- // (provided in |frame|) or the natural width of the title, then
- // limited by the abolute minimum and maximum allowable widths.
- frame.size.width =
- std::min(std::max(bookmarks::kBookmarkMenuButtonMinimumWidth,
- std::max(frame.size.width, desired)),
- bookmarks::kBookmarkMenuButtonMaximumWidth);
-
- BookmarkButton* button = [[[BookmarkButton alloc] initWithFrame:frame]
- autorelease];
- DCHECK(button);
-
- [button setCell:cell];
- [button setDelegate:self];
- if (node) {
- if (node->is_folder()) {
- [button setTarget:self];
- [button setAction:@selector(openBookmarkFolderFromButton:)];
- } else {
- // Make the button do something.
- [button setTarget:self];
- [button setAction:@selector(openBookmark:)];
- // Add a tooltip.
- NSString* title = base::SysUTF16ToNSString(node->GetTitle());
- std::string urlString = node->GetURL().possibly_invalid_spec();
- NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title,
- urlString.c_str()];
- [button setToolTip:tooltip];
- }
- } else {
- [button setEnabled:NO];
- [button setBordered:NO];
- }
- return button;
-}
-
-// Exposed for testing.
-- (NSView*)mainView {
- return mainView_;
-}
-
-- (id)folderTarget {
- return folderTarget_.get();
-}
-
-
-// Our parent controller is another BookmarkBarFolderController, so
-// our window is to the right or left of it. We use a little overlap
-// since it looks much more menu-like than with none. If we would
-// grow off the screen, switch growth to the other direction. Growth
-// direction sticks for folder windows which are descendents of us.
-// If we have tried both directions and neither fits, degrade to a
-// default.
-- (CGFloat)childFolderWindowLeftForWidth:(int)windowWidth {
- // We may legitimately need to try two times (growth to right and
- // left but not in that order). Limit us to three tries in case
- // the folder window can't fit on either side of the screen; we
- // don't want to loop forever.
- CGFloat x;
- int tries = 0;
- while (tries < 2) {
- // Try to grow right.
- if ([self subFolderGrowthToRight]) {
- tries++;
- x = NSMaxX([[parentButton_ window] frame]) -
- bookmarks::kBookmarkMenuOverlap;
- // If off the screen, switch direction.
- if ((x + windowWidth +
- bookmarks::kBookmarkHorizontalScreenPadding) >
- NSMaxX([[[self window] screen] frame])) {
- [self setSubFolderGrowthToRight:NO];
- } else {
- return x;
- }
- }
- // Try to grow left.
- if (![self subFolderGrowthToRight]) {
- tries++;
- x = NSMinX([[parentButton_ window] frame]) +
- bookmarks::kBookmarkMenuOverlap -
- windowWidth;
- // If off the screen, switch direction.
- if (x < NSMinX([[[self window] screen] frame])) {
- [self setSubFolderGrowthToRight:YES];
- } else {
- return x;
- }
- }
- }
- // Unhappy; do the best we can.
- return NSMaxX([[[self window] screen] frame]) - windowWidth;
-}
-
-
-// Compute and return the top left point of our window (screen
-// coordinates). The top left is positioned in a manner similar to
-// cascading menus. Windows may grow to either the right or left of
-// their parent (if a sub-folder) so we need to know |windowWidth|.
-- (NSPoint)windowTopLeftForWidth:(int)windowWidth {
- NSPoint newWindowTopLeft;
- if (![parentController_ isKindOfClass:[self class]]) {
- // If we're not popping up from one of ourselves, we must be
- // popping up from the bookmark bar itself. In this case, start
- // BELOW the parent button. Our left is the button left; our top
- // is bottom of button's parent view.
- NSPoint buttonBottomLeftInScreen =
- [[parentButton_ window]
- convertBaseToScreen:[parentButton_
- convertPoint:NSZeroPoint toView:nil]];
- NSPoint bookmarkBarBottomLeftInScreen =
- [[parentButton_ window]
- convertBaseToScreen:[[parentButton_ superview]
- convertPoint:NSZeroPoint toView:nil]];
- newWindowTopLeft = NSMakePoint(buttonBottomLeftInScreen.x,
- bookmarkBarBottomLeftInScreen.y);
- // Make sure the window is on-screen; if not, push left. It is
- // intentional that top level folders "push left" slightly
- // different than subfolders.
- NSRect screenFrame = [[[parentButton_ window] screen] frame];
- CGFloat spillOff = (newWindowTopLeft.x + windowWidth) - NSMaxX(screenFrame);
- if (spillOff > 0.0) {
- newWindowTopLeft.x = std::max(newWindowTopLeft.x - spillOff,
- NSMinX(screenFrame));
- }
- } else {
- // Parent is a folder; grow right/left.
- newWindowTopLeft.x = [self childFolderWindowLeftForWidth:windowWidth];
- NSPoint top = NSMakePoint(0, (NSMaxY([parentButton_ frame]) +
- bookmarks::kBookmarkVerticalPadding));
- NSPoint topOfWindow =
- [[parentButton_ window]
- convertBaseToScreen:[[parentButton_ superview]
- convertPoint:top toView:nil]];
- newWindowTopLeft.y = topOfWindow.y;
- }
- return newWindowTopLeft;
-}
-
-// Set our window level to the right spot so we're above the menubar, dock, etc.
-// Factored out so we can override/noop in a unit test.
-- (void)configureWindowLevel {
- [[self window] setLevel:NSPopUpMenuWindowLevel];
-}
-
-- (int)windowHeightForButtonCount:(int)buttonCount {
- return (buttonCount * bookmarks::kBookmarkButtonVerticalSpan) +
- bookmarks::kBookmarkVerticalPadding;
-}
-
-- (void)adjustWindowForHeight:(int)windowHeight {
- // Adjust all button widths to be consistent, determine the best size for
- // the window, and set the window frame.
- CGFloat windowWidth =
- [self adjustButtonWidths] +
- (2 * bookmarks::kBookmarkSubMenuHorizontalPadding);
- NSPoint newWindowTopLeft = [self windowTopLeftForWidth:windowWidth];
- NSSize windowSize = NSMakeSize(windowWidth, windowHeight);
- windowSize = [scrollView_ convertSize:windowSize toView:nil];
- NSWindow* window = [self window];
- // If the window is already visible then make sure its top remains stable.
- BOOL windowAlreadyShowing = [window isVisible];
- CGFloat deltaY = windowHeight - NSHeight([mainView_ frame]);
- if (windowAlreadyShowing) {
- NSRect oldFrame = [window frame];
- newWindowTopLeft.y = oldFrame.origin.y + NSHeight(oldFrame);
- }
- NSRect windowFrame = NSMakeRect(newWindowTopLeft.x,
- newWindowTopLeft.y - windowHeight, windowSize.width, windowHeight);
- // Make the scrolled content be the right size (full size).
- NSRect mainViewFrame = NSMakeRect(0, 0, NSWidth(windowFrame) -
- bookmarks::kScrollViewContentWidthMargin, NSHeight(windowFrame));
- [mainView_ setFrame:mainViewFrame];
- // Make sure the window fits on the screen. If not, constrain.
- // We'll scroll to allow the user to see all the content.
- NSRect screenFrame = [[[self window] screen] frame];
- screenFrame = NSInsetRect(screenFrame, 0, kScrollWindowVerticalMargin);
- BOOL wasScrollable = scrollable_;
- if (!NSContainsRect(screenFrame, windowFrame)) {
- scrollable_ = YES;
- windowFrame = NSIntersectionRect(screenFrame, windowFrame);
- } else {
- scrollable_ = NO;
- }
- [window setFrame:windowFrame display:NO];
- if (wasScrollable != scrollable_) {
- // If scrollability changed then rework visibility of the scroll arrows
- // and the scroll offset of the menu view.
- NSSize windowLocalSize =
- [scrollView_ convertSize:windowFrame.size fromView:nil];
- CGFloat scrollPointY = NSHeight(mainViewFrame) - windowLocalSize.height +
- bookmarks::kBookmarkVerticalPadding;
- [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)];
- [self showOrHideScrollArrows];
- [self addOrUpdateScrollTracking];
- } else if (scrollable_ && windowAlreadyShowing) {
- // If the window was already showing and is still scrollable then make
- // sure the main view moves upward, not downward so that the content
- // at the bottom of the menu, not the top, appears to move.
- // The edge case is when the menu is scrolled all the way to top (hence
- // the test of scrollDownArrowShown_) - don't scroll then.
- NSView* superView = [mainView_ superview];
- DCHECK([superView isKindOfClass:[NSClipView class]]);
- NSClipView* clipView = static_cast<NSClipView*>(superView);
- CGFloat scrollPointY = [clipView bounds].origin.y +
- bookmarks::kBookmarkVerticalPadding;
- if (scrollDownArrowShown_ || deltaY > 0.0)
- scrollPointY += deltaY;
- [mainView_ scrollPoint:NSMakePoint(0, scrollPointY)];
- }
- [window display];
-}
-
-// Determine window size and position.
-// Create buttons for all our nodes.
-// TODO(jrg): break up into more and smaller routines for easier unit testing.
-- (void)configureWindow {
- const BookmarkNode* node = [parentButton_ bookmarkNode];
- DCHECK(node);
- int startingIndex = [[parentButton_ cell] startingChildIndex];
- DCHECK_LE(startingIndex, node->GetChildCount());
- // Must have at least 1 button (for "empty")
- int buttons = std::max(node->GetChildCount() - startingIndex, 1);
-
- // Prelim height of the window. We'll trim later as needed.
- int height = [self windowHeightForButtonCount:buttons];
- // We'll need this soon...
- [self window];
-
- // TODO(jrg): combine with frame code in bookmark_bar_controller.mm
- // http://crbug.com/35966
- NSRect buttonsOuterFrame = NSMakeRect(
- bookmarks::kBookmarkSubMenuHorizontalPadding,
- (height - bookmarks::kBookmarkButtonVerticalSpan),
- bookmarks::kDefaultBookmarkWidth,
- bookmarks::kBookmarkButtonHeight);
-
- // TODO(jrg): combine with addNodesToButtonList: code from
- // bookmark_bar_controller.mm (but use y offset)
- // http://crbug.com/35966
- if (!node->GetChildCount()) {
- // If no children we are the empty button.
- BookmarkButton* button = [self makeButtonForNode:nil
- frame:buttonsOuterFrame];
- [buttons_ addObject:button];
- [mainView_ addSubview:button];
- } else {
- for (int i = startingIndex;
- i < node->GetChildCount();
- i++) {
- const BookmarkNode* child = node->GetChild(i);
- BookmarkButton* button = [self makeButtonForNode:child
- frame:buttonsOuterFrame];
- [buttons_ addObject:button];
- [mainView_ addSubview:button];
- buttonsOuterFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan;
- }
- }
-
- [self adjustWindowForHeight:height];
- // Finally pop me up.
- [self configureWindowLevel];
-}
-
-// TODO(mrossetti): See if the following can be moved into view's viewWillDraw:.
-- (CGFloat)adjustButtonWidths {
- CGFloat width = bookmarks::kBookmarkMenuButtonMinimumWidth;
- // Use the cell's size as the base for determining the desired width of the
- // button rather than the button's current width. -[cell cellSize] always
- // returns the 'optimum' size of the cell based on the cell's contents even
- // if it's less than the current button size. Relying on the button size
- // would result in buttons that could only get wider but we want to handle
- // the case where the widest button gets removed from a folder menu.
- for (BookmarkButton* button in buttons_.get())
- width = std::max(width, [[button cell] cellSize].width);
- width = std::min(width, bookmarks::kBookmarkMenuButtonMaximumWidth);
- // Things look and feel more menu-like if all the buttons are the
- // full width of the window, especially if there are submenus.
- for (BookmarkButton* button in buttons_.get()) {
- NSRect buttonFrame = [button frame];
- buttonFrame.size.width = width;
- [button setFrame:buttonFrame];
- }
- return width;
-}
-
-- (BOOL)canScrollUp {
- // If removal of an arrow would make things "finished", state as
- // such.
- CGFloat scrollY = [scrollView_ documentVisibleRect].origin.y;
- if (scrollUpArrowShown_)
- scrollY -= verticalScrollArrowHeight_;
-
- if (scrollY <= 0)
- return NO;
- return YES;
-}
-
-- (BOOL)canScrollDown {
- CGFloat arrowAdjustment = 0.0;
-
- // We do NOT adjust based on the scrollDOWN arrow. This keeps
- // things from "jumping"; if removal of the down arrow (at the top
- // of the window) would cause a scroll to end, we'll end.
- if (scrollUpArrowShown_)
- arrowAdjustment += verticalScrollArrowHeight_;
-
- NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
- NSRect documentRect = [[scrollView_ documentView] frame];
-
- // If we are exactly the right height, return no. We need this
- // extra conditional in the case where we've just scrolled/grown
- // into position.
- if (NSHeight([[self window] frame]) == NSHeight(documentRect))
- return NO;
-
- if ((scrollPosition.y + NSHeight([[self window] frame])) >=
- (NSHeight(documentRect) + arrowAdjustment)) {
- return NO;
- }
- return YES;
-}
-
-- (void)showOrHideScrollArrows {
- NSRect frame = [scrollView_ frame];
- CGFloat scrollDelta = 0.0;
- BOOL canScrollDown = [self canScrollDown];
- BOOL canScrollUp = [self canScrollUp];
-
- if (canScrollUp != scrollUpArrowShown_) {
- if (scrollUpArrowShown_) {
- frame.origin.y -= verticalScrollArrowHeight_;
- frame.size.height += verticalScrollArrowHeight_;
- scrollDelta = verticalScrollArrowHeight_;
- } else {
- frame.origin.y += verticalScrollArrowHeight_;
- frame.size.height -= verticalScrollArrowHeight_;
- scrollDelta = -verticalScrollArrowHeight_;
- }
- }
- if (canScrollDown != scrollDownArrowShown_) {
- if (scrollDownArrowShown_) {
- frame.size.height += verticalScrollArrowHeight_;
- } else {
- frame.size.height -= verticalScrollArrowHeight_;
- }
- }
- scrollUpArrowShown_ = canScrollUp;
- scrollDownArrowShown_ = canScrollDown;
- [scrollView_ setFrame:frame];
-
- // Adjust scroll based on new frame. For example, if we make room
- // for an arrow at the bottom, adjust the scroll so the topmost item
- // is still fully visible.
- if (scrollDelta) {
- NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
- scrollPosition.y -= scrollDelta;
- [[scrollView_ documentView] scrollPoint:scrollPosition];
- }
-}
-
-- (BOOL)scrollable {
- return scrollable_;
-}
-
-// Start a "scroll up" timer.
-- (void)beginScrollWindowUp {
- [self addScrollTimerWithDelta:kBookmarkBarFolderScrollAmount];
-}
-
-// Start a "scroll down" timer.
-- (void)beginScrollWindowDown {
- [self addScrollTimerWithDelta:-kBookmarkBarFolderScrollAmount];
-}
-
-// End a scrolling timer. Can be called excessively with no harm.
-- (void)endScroll {
- if (scrollTimer_) {
- [scrollTimer_ invalidate];
- scrollTimer_ = nil;
- verticalScrollDelta_ = 0;
- }
-}
-
-// Perform a single scroll of the specified amount.
-// Scroll up:
-// Scroll the documentView by the growth amount.
-// If we cannot grow the window, simply scroll the documentView.
-// If we can grow the window up without falling off the screen, do it.
-// Scroll down:
-// Never change the window size; only scroll the documentView.
-- (void)performOneScroll:(CGFloat)delta {
- NSRect windowFrame = [[self window] frame];
- NSRect screenFrame = [[[self window] screen] frame];
-
- // First scroll the "document" area.
- NSPoint scrollPosition = [scrollView_ documentVisibleRect].origin;
- scrollPosition.y -= delta;
- [[scrollView_ documentView] scrollPoint:scrollPosition];
-
- if (buttonThatMouseIsIn_)
- [buttonThatMouseIsIn_ toggleButtonBorderingWhileMouseInside];
-
- // We update the window size after shifting the scroll to avoid a race.
- CGFloat screenHeightMinusMargin = (NSHeight(screenFrame) -
- (2 * kScrollWindowVerticalMargin));
- if (delta) {
- // If we can, grow the window (up).
- if (NSHeight(windowFrame) < screenHeightMinusMargin) {
- CGFloat growAmount = delta;
- // Don't scroll more than enough to "finish".
- if (scrollPosition.y < 0)
- growAmount += scrollPosition.y;
- windowFrame.size.height += growAmount;
- windowFrame.size.height = std::min(NSHeight(windowFrame),
- screenHeightMinusMargin);
- // Watch out for a finish that isn't the full height of the screen.
- // We get here if using the scroll wheel to scroll by small amounts.
- windowFrame.size.height = std::min(NSHeight(windowFrame),
- NSHeight([mainView_ frame]));
- // Don't allow scrolling to make the window smaller, ever. This
- // conditional is important when processing scrollWheel events.
- if (windowFrame.size.height > [[self window] frame].size.height) {
- [[self window] setFrame:windowFrame display:YES];
- [self addOrUpdateScrollTracking];
- }
- }
- }
-
- // If we're at either end, happiness.
- if ((scrollPosition.y <= 0) ||
- ((scrollPosition.y + NSHeight(windowFrame) >=
- NSHeight([mainView_ frame])) &&
- (windowFrame.size.height == screenHeightMinusMargin))) {
- [self endScroll];
-
- // If we can't scroll either up or down we are completely done.
- // For example, perhaps we've scrolled a little and grown the
- // window on-screen until there is now room for everything.
- if (![self canScrollUp] && ![self canScrollDown]) {
- scrollable_ = NO;
- [self removeScrollTracking];
- }
- }
-
- [self showOrHideScrollArrows];
-}
-
-// Perform a scroll of the window on the screen.
-// Called by a timer when scrolling.
-- (void)performScroll:(NSTimer*)timer {
- DCHECK(verticalScrollDelta_);
- [self performOneScroll:verticalScrollDelta_];
-}
-
-
-// Add a timer to fire at a regular interveral which scrolls the
-// window vertically |delta|.
-- (void)addScrollTimerWithDelta:(CGFloat)delta {
- if (scrollTimer_ && verticalScrollDelta_ == delta)
- return;
- [self endScroll];
- verticalScrollDelta_ = delta;
- scrollTimer_ =
- [NSTimer scheduledTimerWithTimeInterval:kBookmarkBarFolderScrollInterval
- target:self
- selector:@selector(performScroll:)
- userInfo:nil
- repeats:YES];
-}
-
-// Called as a result of our tracking area. Warning: on the main
-// screen (of a single-screened machine), the minimum mouse y value is
-// 1, not 0. Also, we do not get events when the mouse is above the
-// menubar (to be fixed by setting the proper window level; see
-// initializer).
-- (void)mouseMoved:(NSEvent*)theEvent {
- DCHECK([theEvent window] == [self window]);
-
- NSPoint eventScreenLocation =
- [[theEvent window] convertBaseToScreen:[theEvent locationInWindow]];
-
- // We use frame (not visibleFrame) since our bookmark folder is on
- // TOP of the menubar.
- NSRect visibleRect = [[[self window] screen] frame];
- CGFloat closeToTopOfScreen = NSMaxY(visibleRect) -
- verticalScrollArrowHeight_;
- CGFloat closeToBottomOfScreen = NSMinY(visibleRect) +
- verticalScrollArrowHeight_;
-
- if (eventScreenLocation.y <= closeToBottomOfScreen) {
- [self beginScrollWindowUp];
- } else if (eventScreenLocation.y > closeToTopOfScreen) {
- [self beginScrollWindowDown];
- } else {
- [self endScroll];
- }
-}
-
-- (void)mouseExited:(NSEvent*)theEvent {
- [self endScroll];
-}
-
-// Add a tracking area so we know when the mouse is pinned to the top
-// or bottom of the screen. If that happens, and if the mouse
-// position overlaps the window, scroll it.
-- (void)addOrUpdateScrollTracking {
- [self removeScrollTracking];
- NSView* view = [[self window] contentView];
- scrollTrackingArea_.reset([[NSTrackingArea alloc]
- initWithRect:[view bounds]
- options:(NSTrackingMouseMoved |
- NSTrackingMouseEnteredAndExited |
- NSTrackingActiveAlways)
- owner:self
- userInfo:nil]);
- [view addTrackingArea:scrollTrackingArea_];
-}
-
-// Remove the tracking area associated with scrolling.
-- (void)removeScrollTracking {
- if (scrollTrackingArea_.get()) {
- [[[self window] contentView] removeTrackingArea:scrollTrackingArea_];
- }
- scrollTrackingArea_.reset();
-}
-
-// Delegate callback.
-- (void)windowWillClose:(NSNotification*)notification {
- // If a "hover open" is pending when the bookmark bar folder is
- // closed, be sure it gets cancelled.
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
-
- [barController_ childFolderWillClose:self];
- [self closeBookmarkFolder:self];
- [self autorelease];
-}
-
-// Close the old hover-open bookmark folder, and open a new one. We
-// do both in one step to allow for a delay in closing the old one.
-// See comments above kDragHoverCloseDelay (bookmark_bar_controller.h)
-// for more details.
-- (void)openBookmarkFolderFromButtonAndCloseOldOne:(id)sender {
- // If an old submenu exists, close it immediately.
- [self closeBookmarkFolder:sender];
-
- // Open a new one if meaningful.
- if ([sender isFolder])
- [folderTarget_ openBookmarkFolderFromButton:sender];
-}
-
-- (NSArray*)buttons {
- return buttons_.get();
-}
-
-- (void)close {
- [folderController_ close];
- [super close];
-}
-
-- (void)scrollWheel:(NSEvent *)theEvent {
- if (scrollable_) {
- // We go negative since an NSScrollView has a flipped coordinate frame.
- CGFloat amt = kBookmarkBarFolderScrollWheelAmount * -[theEvent deltaY];
- [self performOneScroll:amt];
- }
-}
-
-#pragma mark Actions Forwarded to Parent BookmarkBarController
-
-- (IBAction)openBookmark:(id)sender {
- [barController_ openBookmark:sender];
-}
-
-- (IBAction)openBookmarkInNewForegroundTab:(id)sender {
- [barController_ openBookmarkInNewForegroundTab:sender];
-}
-
-- (IBAction)openBookmarkInNewWindow:(id)sender {
- [barController_ openBookmarkInNewWindow:sender];
-}
-
-- (IBAction)openBookmarkInIncognitoWindow:(id)sender {
- [barController_ openBookmarkInIncognitoWindow:sender];
-}
-
-- (IBAction)editBookmark:(id)sender {
- [barController_ editBookmark:sender];
-}
-
-- (IBAction)cutBookmark:(id)sender {
- [self closeBookmarkFolder:self];
- [barController_ cutBookmark:sender];
-}
-
-- (IBAction)copyBookmark:(id)sender {
- [barController_ copyBookmark:sender];
-}
-
-- (IBAction)pasteBookmark:(id)sender {
- [barController_ pasteBookmark:sender];
-}
-
-- (IBAction)deleteBookmark:(id)sender {
- [self closeBookmarkFolder:self];
- [barController_ deleteBookmark:sender];
-}
-
-- (IBAction)openAllBookmarks:(id)sender {
- [barController_ openAllBookmarks:sender];
-}
-
-- (IBAction)openAllBookmarksNewWindow:(id)sender {
- [barController_ openAllBookmarksNewWindow:sender];
-}
-
-- (IBAction)openAllBookmarksIncognitoWindow:(id)sender {
- [barController_ openAllBookmarksIncognitoWindow:sender];
-}
-
-- (IBAction)addPage:(id)sender {
- [barController_ addPage:sender];
-}
-
-- (IBAction)addFolder:(id)sender {
- [barController_ addFolder:sender];
-}
-
-#pragma mark Drag & Drop
-
-// Find something like std::is_between<T>? I can't believe one doesn't exist.
-// http://crbug.com/35966
-static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
- return ((value >= low) && (value <= high));
-}
-
-// Return the proposed drop target for a hover open button, or nil if none.
-//
-// TODO(jrg): this is just like the version in
-// bookmark_bar_controller.mm, but vertical instead of horizontal.
-// Generalize to be axis independent then share code.
-// http://crbug.com/35966
-- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point {
- for (BookmarkButton* button in buttons_.get()) {
- // No early break -- makes no assumption about button ordering.
-
- // Intentionally NOT using NSPointInRect() so that scrolling into
- // a submenu doesn't cause it to be closed.
- if (ValueInRangeInclusive(NSMinY([button frame]),
- point.y,
- NSMaxY([button frame]))) {
-
- // Over a button but let's be a little more specific
- // (e.g. over the middle half).
- NSRect frame = [button frame];
- NSRect middleHalfOfButton = NSInsetRect(frame, 0, frame.size.height / 4);
- if (ValueInRangeInclusive(NSMinY(middleHalfOfButton),
- point.y,
- NSMaxY(middleHalfOfButton))) {
- // It makes no sense to drop on a non-folder; there is no hover.
- if (![button isFolder])
- return nil;
- // Got it!
- return button;
- } else {
- // Over a button but not over the middle half.
- return nil;
- }
- }
- }
- // Not hovering over a button.
- return nil;
-}
-
-// TODO(jrg): again we have code dup, sort of, with
-// bookmark_bar_controller.mm, but the axis is changed. One minor
-// difference is accomodation for the "empty" button (which may not
-// exist in the future).
-// http://crbug.com/35966
-- (int)indexForDragToPoint:(NSPoint)point {
- // Identify which buttons we are between. For now, assume a button
- // location is at the center point of its view, and that an exact
- // match means "place before".
- // TODO(jrg): revisit position info based on UI team feedback.
- // dropLocation is in bar local coordinates.
- // http://crbug.com/36276
- NSPoint dropLocation =
- [mainView_ convertPoint:point
- fromView:[[self window] contentView]];
- BookmarkButton* buttonToTheTopOfDraggedButton = nil;
- // Buttons are laid out in this array from top to bottom (screen
- // wise), which means "biggest y" --> "smallest y".
- for (BookmarkButton* button in buttons_.get()) {
- CGFloat midpoint = NSMidY([button frame]);
- if (dropLocation.y > midpoint) {
- break;
- }
- buttonToTheTopOfDraggedButton = button;
- }
-
- // TODO(jrg): On Windows, dropping onto (empty) highlights the
- // entire drop location and does not use an insertion point.
- // http://crbug.com/35967
- if (!buttonToTheTopOfDraggedButton) {
- // We are at the very top (we broke out of the loop on the first try).
- return 0;
- }
- if ([buttonToTheTopOfDraggedButton isEmpty]) {
- // There is a button but it's an empty placeholder.
- // Default to inserting on top of it.
- return 0;
- }
- const BookmarkNode* beforeNode = [buttonToTheTopOfDraggedButton
- bookmarkNode];
- DCHECK(beforeNode);
- // Be careful if the number of buttons != number of nodes.
- return ((beforeNode->GetParent()->IndexOfChild(beforeNode) + 1) -
- [[parentButton_ cell] startingChildIndex]);
-}
-
-// TODO(jrg): Yet more code dup.
-// http://crbug.com/35966
-- (BOOL)dragBookmark:(const BookmarkNode*)sourceNode
- to:(NSPoint)point
- copy:(BOOL)copy {
- DCHECK(sourceNode);
-
- // Drop destination.
- const BookmarkNode* destParent = NULL;
- int destIndex = 0;
-
- // First check if we're dropping on a button. If we have one, and
- // it's a folder, drop in it.
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
- if ([button isFolder]) {
- destParent = [button bookmarkNode];
- // Drop it at the end.
- destIndex = [button bookmarkNode]->GetChildCount();
- } else {
- // Else we're dropping somewhere in the folder, so find the right spot.
- destParent = [parentButton_ bookmarkNode];
- destIndex = [self indexForDragToPoint:point];
- // Be careful if the number of buttons != number of nodes.
- destIndex += [[parentButton_ cell] startingChildIndex];
- }
-
- // Prevent cycles.
- BOOL wasCopiedOrMoved = NO;
- if (!destParent->HasAncestor(sourceNode)) {
- if (copy)
- [self bookmarkModel]->Copy(sourceNode, destParent, destIndex);
- else
- [self bookmarkModel]->Move(sourceNode, destParent, destIndex);
- wasCopiedOrMoved = YES;
- // Movement of a node triggers observers (like us) to rebuild the
- // bar so we don't have to do so explicitly.
- }
-
- return wasCopiedOrMoved;
-}
-
-#pragma mark BookmarkButtonDelegate Protocol
-
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button {
- [[self folderTarget] fillPasteboard:pboard forDragOfButton:button];
-
- // Close our folder menu and submenus since we know we're going to be dragged.
- [self closeBookmarkFolder:self];
-}
-
-// Called from BookmarkButton.
-// Unlike bookmark_bar_controller's version, we DO default to being enabled.
-- (void)mouseEnteredButton:(id)sender event:(NSEvent*)event {
- buttonThatMouseIsIn_ = sender;
-
- // Cancel a previous hover if needed.
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
-
- // If already opened, then we exited but re-entered the button
- // (without entering another button open), do nothing.
- if ([folderController_ parentButton] == sender)
- return;
-
- [self performSelector:@selector(openBookmarkFolderFromButtonAndCloseOldOne:)
- withObject:sender
- afterDelay:bookmarks::kHoverOpenDelay];
-}
-
-// Called from the BookmarkButton
-- (void)mouseExitedButton:(id)sender event:(NSEvent*)event {
- if (buttonThatMouseIsIn_ == sender)
- buttonThatMouseIsIn_ = nil;
-
- // Stop any timer about opening a new hover-open folder.
-
- // Since a performSelector:withDelay: on self retains self, it is
- // possible that a cancelPreviousPerformRequestsWithTarget: reduces
- // the refcount to 0, releasing us. That's a bad thing to do while
- // this object (or others it may own) is in the event chain. Thus
- // we have a retain/autorelease.
- [self retain];
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
- [self autorelease];
-}
-
-- (NSWindow*)browserWindow {
- return [parentController_ browserWindow];
-}
-
-- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
- return [barController_ canEditBookmark:[button bookmarkNode]];
-}
-
-- (void)didDragBookmarkToTrash:(BookmarkButton*)button {
- // TODO(mrossetti): Refactor BookmarkBarFolder common code.
- // http://crbug.com/35966
- const BookmarkNode* node = [button bookmarkNode];
- if (node) {
- const BookmarkNode* parent = node->GetParent();
- [self bookmarkModel]->Remove(parent,
- parent->IndexOfChild(node));
- }
-}
-
-#pragma mark BookmarkButtonControllerProtocol
-
-// Recursively close all bookmark folders.
-- (void)closeAllBookmarkFolders {
- // Closing the top level implicitly closes all children.
- [barController_ closeAllBookmarkFolders];
-}
-
-// Close our bookmark folder (a sub-controller) if we have one.
-- (void)closeBookmarkFolder:(id)sender {
- if (folderController_) {
- [self setSubFolderGrowthToRight:YES];
- [[folderController_ window] close];
- folderController_ = nil;
- }
-}
-
-- (BookmarkModel*)bookmarkModel {
- return [barController_ bookmarkModel];
-}
-
-// TODO(jrg): Refactor BookmarkBarFolder common code. http://crbug.com/35966
-// Most of the work (e.g. drop indicator) is taken care of in the
-// folder_view. Here we handle hover open issues for subfolders.
-// Caution: there are subtle differences between this one and
-// bookmark_bar_controller.mm's version.
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- NSPoint currentLocation = [info draggingLocation];
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:currentLocation];
-
- // Don't allow drops that would result in cycles.
- if (button) {
- NSData* data = [[info draggingPasteboard]
- dataForType:kBookmarkButtonDragType];
- if (data && [info draggingSource]) {
- BookmarkButton* sourceButton = nil;
- [data getBytes:&sourceButton length:sizeof(sourceButton)];
- const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
- const BookmarkNode* destNode = [button bookmarkNode];
- if (destNode->HasAncestor(sourceNode))
- button = nil;
- }
- }
- // Delegate handling of dragging over a button to the |hoverState_| member.
- return [hoverState_ draggingEnteredButton:button];
-}
-
-// Unlike bookmark_bar_controller, we need to keep track of dragging state.
-// We also need to make sure we cancel the delayed hover close.
-- (void)draggingExited:(id<NSDraggingInfo>)info {
- // NOT the same as a cancel --> we may have moved the mouse into the submenu.
- // Delegate handling of the hover button to the |hoverState_| member.
- [hoverState_ draggingExited];
-}
-
-- (BOOL)dragShouldLockBarVisibility {
- return [parentController_ dragShouldLockBarVisibility];
-}
-
-// TODO(jrg): ARGH more code dup.
-// http://crbug.com/35966
-- (BOOL)dragButton:(BookmarkButton*)sourceButton
- to:(NSPoint)point
- copy:(BOOL)copy {
- DCHECK([sourceButton isKindOfClass:[BookmarkButton class]]);
- const BookmarkNode* sourceNode = [sourceButton bookmarkNode];
- return [self dragBookmark:sourceNode to:point copy:copy];
-}
-
-// TODO(mrossetti,jrg): Identical to the same function in BookmarkBarController.
-// http://crbug.com/35966
-- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info {
- BOOL dragged = NO;
- std::vector<const BookmarkNode*> nodes([self retrieveBookmarkNodeData]);
- if (nodes.size()) {
- BOOL copy = !([info draggingSourceOperationMask] & NSDragOperationMove);
- NSPoint dropPoint = [info draggingLocation];
- for (std::vector<const BookmarkNode*>::const_iterator it = nodes.begin();
- it != nodes.end(); ++it) {
- const BookmarkNode* sourceNode = *it;
- dragged = [self dragBookmark:sourceNode to:dropPoint copy:copy];
- }
- }
- return dragged;
-}
-
-// TODO(mrossetti,jrg): Identical to the same function in BookmarkBarController.
-// http://crbug.com/35966
-- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData {
- std::vector<const BookmarkNode*> dragDataNodes;
- BookmarkNodeData dragData;
- if(dragData.ReadFromDragClipboard()) {
- BookmarkModel* bookmarkModel = [self bookmarkModel];
- Profile* profile = bookmarkModel->profile();
- std::vector<const BookmarkNode*> nodes(dragData.GetNodes(profile));
- dragDataNodes.assign(nodes.begin(), nodes.end());
- }
- return dragDataNodes;
-}
-
-// Return YES if we should show the drop indicator, else NO.
-// TODO(jrg): ARGH code dup!
-// http://crbug.com/35966
-- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point {
- return ![self buttonForDroppingOnAtPoint:point];
-}
-
-// Return the y position for a drop indicator.
-//
-// TODO(jrg): again we have code dup, sort of, with
-// bookmark_bar_controller.mm, but the axis is changed.
-// http://crbug.com/35966
-- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point {
- CGFloat y = 0;
- int destIndex = [self indexForDragToPoint:point];
- int numButtons = static_cast<int>([buttons_ count]);
-
- // If it's a drop strictly between existing buttons or at the very beginning
- if (destIndex >= 0 && destIndex < numButtons) {
- // ... put the indicator right between the buttons.
- BookmarkButton* button =
- [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex)];
- DCHECK(button);
- NSRect buttonFrame = [button frame];
- y = NSMaxY(buttonFrame) + 0.5 * bookmarks::kBookmarkVerticalPadding;
-
- // If it's a drop at the end (past the last button, if there are any) ...
- } else if (destIndex == numButtons) {
- // and if it's past the last button ...
- if (numButtons > 0) {
- // ... find the last button, and put the indicator below it.
- BookmarkButton* button =
- [buttons_ objectAtIndex:static_cast<NSUInteger>(destIndex - 1)];
- DCHECK(button);
- NSRect buttonFrame = [button frame];
- y = buttonFrame.origin.y - 0.5 * bookmarks::kBookmarkVerticalPadding;
-
- }
- } else {
- NOTREACHED();
- }
-
- return y;
-}
-
-- (ThemeProvider*)themeProvider {
- return [parentController_ themeProvider];
-}
-
-- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child {
- // Do nothing.
-}
-
-- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child {
- // Do nothing.
-}
-
-- (BookmarkBarFolderController*)folderController {
- return folderController_;
-}
-
-// Add a new folder controller as triggered by the given folder button.
-- (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton {
- if (folderController_)
- [self closeBookmarkFolder:self];
-
- // Folder controller, like many window controllers, owns itself.
- folderController_ =
- [[BookmarkBarFolderController alloc] initWithParentButton:parentButton
- parentController:self
- barController:barController_];
- [folderController_ showWindow:self];
-}
-
-- (void)openAll:(const BookmarkNode*)node
- disposition:(WindowOpenDisposition)disposition {
- [barController_ openAll:node disposition:disposition];
-}
-
-- (void)addButtonForNode:(const BookmarkNode*)node
- atIndex:(NSInteger)buttonIndex {
- // Propose the frame for the new button. By default, this will be set to the
- // topmost button's frame (and there will always be one) offset upward in
- // anticipation of insertion.
- NSRect newButtonFrame = [[buttons_ objectAtIndex:0] frame];
- newButtonFrame.origin.y += bookmarks::kBookmarkButtonVerticalSpan;
- // When adding a button to an empty folder we must remove the 'empty'
- // placeholder button. This can be detected by checking for a parent
- // child count of 1.
- const BookmarkNode* parentNode = node->GetParent();
- if (parentNode->GetChildCount() == 1) {
- BookmarkButton* emptyButton = [buttons_ lastObject];
- newButtonFrame = [emptyButton frame];
- [emptyButton setDelegate:nil];
- [emptyButton removeFromSuperview];
- [buttons_ removeLastObject];
- }
-
- if (buttonIndex == -1 || buttonIndex > (NSInteger)[buttons_ count])
- buttonIndex = [buttons_ count];
-
- // Offset upward by one button height all buttons above insertion location.
- BookmarkButton* button = nil; // Remember so it can be de-highlighted.
- for (NSInteger i = 0; i < buttonIndex; ++i) {
- button = [buttons_ objectAtIndex:i];
- // Remember this location in case it's the last button being moved
- // which is where the new button will be located.
- newButtonFrame = [button frame];
- NSRect buttonFrame = [button frame];
- buttonFrame.origin.y += bookmarks::kBookmarkButtonVerticalSpan;
- [button setFrame:buttonFrame];
- }
- [[button cell] mouseExited:nil]; // De-highlight.
- BookmarkButton* newButton = [self makeButtonForNode:node
- frame:newButtonFrame];
- [buttons_ insertObject:newButton atIndex:buttonIndex];
- [mainView_ addSubview:newButton];
-
- // Close any child folder(s) which may still be open.
- [self closeBookmarkFolder:self];
-
- // Prelim height of the window. We'll trim later as needed.
- int height = [self windowHeightForButtonCount:[buttons_ count]];
- [self adjustWindowForHeight:height];
-}
-
-// More code which essentially duplicates that of BookmarkBarController.
-// TODO(mrossetti,jrg): http://crbug.com/35966
-- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point {
- DCHECK([urls count] == [titles count]);
- BOOL nodesWereAdded = NO;
- // Figure out where these new bookmarks nodes are to be added.
- BookmarkButton* button = [self buttonForDroppingOnAtPoint:point];
- BookmarkModel* bookmarkModel = [self bookmarkModel];
- const BookmarkNode* destParent = NULL;
- int destIndex = 0;
- if ([button isFolder]) {
- destParent = [button bookmarkNode];
- // Drop it at the end.
- destIndex = [button bookmarkNode]->GetChildCount();
- } else {
- // Else we're dropping somewhere in the folder, so find the right spot.
- destParent = [parentButton_ bookmarkNode];
- destIndex = [self indexForDragToPoint:point];
- // Be careful if the number of buttons != number of nodes.
- destIndex += [[parentButton_ cell] startingChildIndex];
- }
-
- // Create and add the new bookmark nodes.
- size_t urlCount = [urls count];
- for (size_t i = 0; i < urlCount; ++i) {
- GURL gurl;
- const char* string = [[urls objectAtIndex:i] UTF8String];
- if (string)
- gurl = GURL(string);
- // We only expect to receive valid URLs.
- DCHECK(gurl.is_valid());
- if (gurl.is_valid()) {
- bookmarkModel->AddURL(destParent,
- destIndex++,
- base::SysNSStringToUTF16([titles objectAtIndex:i]),
- gurl);
- nodesWereAdded = YES;
- }
- }
- return nodesWereAdded;
-}
-
-- (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {
- if (fromIndex != toIndex) {
- if (toIndex == -1)
- toIndex = [buttons_ count];
- BookmarkButton* movedButton = [buttons_ objectAtIndex:fromIndex];
- [buttons_ removeObjectAtIndex:fromIndex];
- NSRect movedFrame = [movedButton frame];
- NSPoint toOrigin = movedFrame.origin;
- [movedButton setHidden:YES];
- if (fromIndex < toIndex) {
- BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex - 1];
- toOrigin = [targetButton frame].origin;
- for (NSInteger i = fromIndex; i < toIndex; ++i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect frame = [button frame];
- frame.origin.y += bookmarks::kBookmarkButtonVerticalSpan;
- [button setFrameOrigin:frame.origin];
- }
- } else {
- BookmarkButton* targetButton = [buttons_ objectAtIndex:toIndex];
- toOrigin = [targetButton frame].origin;
- for (NSInteger i = fromIndex - 1; i >= toIndex; --i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect buttonFrame = [button frame];
- buttonFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan;
- [button setFrameOrigin:buttonFrame.origin];
- }
- }
- [buttons_ insertObject:movedButton atIndex:toIndex];
- [movedButton setFrameOrigin:toOrigin];
- [movedButton setHidden:NO];
- }
-}
-
-// TODO(jrg): Refactor BookmarkBarFolder common code. http://crbug.com/35966
-- (void)removeButton:(NSInteger)buttonIndex animate:(BOOL)animate {
- // TODO(mrossetti): Get disappearing animation to work. http://crbug.com/42360
- BookmarkButton* oldButton = [buttons_ objectAtIndex:buttonIndex];
- NSPoint poofPoint = [oldButton screenLocationForRemoveAnimation];
-
- // If a hover-open is pending, cancel it.
- if (oldButton == buttonThatMouseIsIn_) {
- [NSObject cancelPreviousPerformRequestsWithTarget:self];
- buttonThatMouseIsIn_ = nil;
- }
-
- // Deleting a button causes rearrangement that enables us to lose a
- // mouse-exited event. This problem doesn't appear to exist with
- // other keep-menu-open options (e.g. add folder). Since the
- // showsBorderOnlyWhileMouseInside uses a tracking area, simple
- // tricks (e.g. sending an extra mouseExited: to the button) don't
- // fix the problem.
- // http://crbug.com/54324
- for (NSButton* button in buttons_.get()) {
- if ([button showsBorderOnlyWhileMouseInside]) {
- [button setShowsBorderOnlyWhileMouseInside:NO];
- [button setShowsBorderOnlyWhileMouseInside:YES];
- }
- }
-
- [oldButton setDelegate:nil];
- [oldButton removeFromSuperview];
- if (animate && !ignoreAnimations_)
- NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,
- NSZeroSize, nil, nil, nil);
- [buttons_ removeObjectAtIndex:buttonIndex];
- for (NSInteger i = 0; i < buttonIndex; ++i) {
- BookmarkButton* button = [buttons_ objectAtIndex:i];
- NSRect buttonFrame = [button frame];
- buttonFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan;
- [button setFrame:buttonFrame];
- }
- // Search for and adjust submenus, if necessary.
- NSInteger buttonCount = [buttons_ count];
- if (buttonCount) {
- BookmarkButton* subButton = [folderController_ parentButton];
- for (NSInteger i = buttonIndex; i < buttonCount; ++i) {
- BookmarkButton* aButton = [buttons_ objectAtIndex:i];
- // If this button is showing its menu then we need to move the menu, too.
- if (aButton == subButton)
- [folderController_ offsetFolderMenuWindow:NSMakeSize(0.0,
- bookmarks::kBookmarkBarHeight)];
- }
- } else {
- // If all nodes have been removed from this folder then add in the
- // 'empty' placeholder button.
- NSRect buttonFrame =
- NSMakeRect(bookmarks::kBookmarkSubMenuHorizontalPadding,
- bookmarks::kBookmarkButtonHeight -
- (bookmarks::kBookmarkBarHeight -
- bookmarks::kBookmarkVerticalPadding),
- bookmarks::kDefaultBookmarkWidth,
- (bookmarks::kBookmarkBarHeight -
- 2 * bookmarks::kBookmarkVerticalPadding));
- BookmarkButton* button = [self makeButtonForNode:nil
- frame:buttonFrame];
- [buttons_ addObject:button];
- [mainView_ addSubview:button];
- buttonCount = 1;
- }
-
- // Propose a height for the window. We'll trim later as needed.
- [self adjustWindowForHeight:[self windowHeightForButtonCount:buttonCount]];
-}
-
-- (id<BookmarkButtonControllerProtocol>)controllerForNode:
- (const BookmarkNode*)node {
- // See if we are holding this node, otherwise see if it is in our
- // hierarchy of visible folder menus.
- if ([parentButton_ bookmarkNode] == node)
- return self;
- return [folderController_ controllerForNode:node];
-}
-
-#pragma mark TestingAPI Only
-
-- (void)setIgnoreAnimations:(BOOL)ignore {
- ignoreAnimations_ = ignore;
-}
-
-- (BookmarkButton*)buttonThatMouseIsIn {
- return buttonThatMouseIsIn_;
-}
-
-@end // BookmarkBarFolderController
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
deleted file mode 100644
index 890c0fc..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
+++ /dev/null
@@ -1,1552 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/basictypes.h"
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_button_cell.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/cocoa/view_resizer_pong.h"
-#include "chrome/test/model_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-// Add a redirect to make testing easier.
-@interface BookmarkBarFolderController(MakeTestingEasier)
-- (IBAction)openBookmarkFolderFromButton:(id)sender;
-- (void)validateMenuSpacing;
-@end
-
-@implementation BookmarkBarFolderController(MakeTestingEasier)
-- (IBAction)openBookmarkFolderFromButton:(id)sender {
- [[self folderTarget] openBookmarkFolderFromButton:sender];
-}
-
-// Utility function to verify that the buttons in this folder are all
-// evenly spaced in a progressive manner.
-- (void)validateMenuSpacing {
- BOOL firstButton = YES;
- CGFloat lastVerticalOffset = 0.0;
- for (BookmarkButton* button in [self buttons]) {
- if (firstButton) {
- firstButton = NO;
- lastVerticalOffset = [button frame].origin.y;
- } else {
- CGFloat nextVerticalOffset = [button frame].origin.y;
- EXPECT_CGFLOAT_EQ(lastVerticalOffset -
- bookmarks::kBookmarkButtonVerticalSpan,
- nextVerticalOffset);
- lastVerticalOffset = nextVerticalOffset;
- }
- }
-}
-@end
-
-// Don't use a high window level when running unit tests -- it'll
-// interfere with anything else you are working on.
-// For testing.
-@interface BookmarkBarFolderControllerNoLevel : BookmarkBarFolderController
-@end
-
-@implementation BookmarkBarFolderControllerNoLevel
-- (void)configureWindowLevel {
- // Intentionally empty.
-}
-@end
-
-// No window level and the ability to fake the "top left" point of the window.
-// For testing.
-@interface BookmarkBarFolderControllerLow : BookmarkBarFolderControllerNoLevel {
- BOOL realTopLeft_; // Use the real windowTopLeft call?
-}
-@property (nonatomic) BOOL realTopLeft;
-@end
-
-
-@implementation BookmarkBarFolderControllerLow
-
-@synthesize realTopLeft = realTopLeft_;
-
-- (NSPoint)windowTopLeftForWidth:(int)width {
- return realTopLeft_ ? [super windowTopLeftForWidth:width] :
- NSMakePoint(200,200);
-}
-
-@end
-
-
-@interface BookmarkBarFolderControllerPong : BookmarkBarFolderControllerLow {
- BOOL childFolderWillShow_;
- BOOL childFolderWillClose_;
-}
-@property (nonatomic, readonly) BOOL childFolderWillShow;
-@property (nonatomic, readonly) BOOL childFolderWillClose;
-@end
-
-@implementation BookmarkBarFolderControllerPong
-@synthesize childFolderWillShow = childFolderWillShow_;
-@synthesize childFolderWillClose = childFolderWillClose_;
-
-- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child {
- childFolderWillShow_ = YES;
-}
-
-- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child {
- childFolderWillClose_ = YES;
-}
-
-// We don't have a real BookmarkBarController as our parent root so
-// we fake this one out.
-- (void)closeAllBookmarkFolders {
- [self closeBookmarkFolder:self];
-}
-
-@end
-
-namespace {
-const int kLotsOfNodesCount = 150;
-};
-
-
-// Redirect certain calls so they can be seen by tests.
-
-@interface BookmarkBarControllerChildFolderRedirect : BookmarkBarController {
- BookmarkBarFolderController* childFolderDelegate_;
-}
-@property (nonatomic, assign) BookmarkBarFolderController* childFolderDelegate;
-@end
-
-@implementation BookmarkBarControllerChildFolderRedirect
-
-@synthesize childFolderDelegate = childFolderDelegate_;
-
-- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child {
- [childFolderDelegate_ childFolderWillShow:child];
-}
-
-- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child {
- [childFolderDelegate_ childFolderWillClose:child];
-}
-
-@end
-
-
-class BookmarkBarFolderControllerTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
- scoped_nsobject<BookmarkBarControllerChildFolderRedirect> bar_;
- const BookmarkNode* folderA_; // owned by model
- const BookmarkNode* longTitleNode_; // owned by model
-
- BookmarkBarFolderControllerTest() {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folderA = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
- folderA_ = folderA;
- model->AddGroup(parent, parent->GetChildCount(),
- ASCIIToUTF16("sibbling group"));
- const BookmarkNode* folderB = model->AddGroup(folderA,
- folderA->GetChildCount(),
- ASCIIToUTF16("subgroup 1"));
- model->AddGroup(folderA,
- folderA->GetChildCount(),
- ASCIIToUTF16("subgroup 2"));
- model->AddURL(folderA, folderA->GetChildCount(), ASCIIToUTF16("title a"),
- GURL("http://www.google.com/a"));
- longTitleNode_ = model->AddURL(
- folderA, folderA->GetChildCount(),
- ASCIIToUTF16("title super duper long long whoa momma title you betcha"),
- GURL("http://www.google.com/b"));
- model->AddURL(folderB, folderB->GetChildCount(), ASCIIToUTF16("t"),
- GURL("http://www.google.com/c"));
-
- bar_.reset(
- [[BookmarkBarControllerChildFolderRedirect alloc]
- initWithBrowser:helper_.browser()
- initialWidth:300
- delegate:nil
- resizeDelegate:nil]);
- [bar_ loaded:model];
- // Make parent frame for bookmark bar then open it.
- NSRect frame = [[test_window() contentView] frame];
- frame = NSInsetRect(frame, 100, 200);
- NSView* fakeToolbarView = [[[NSView alloc] initWithFrame:frame]
- autorelease];
- [[test_window() contentView] addSubview:fakeToolbarView];
- [fakeToolbarView addSubview:[bar_ view]];
- [bar_ setBookmarkBarEnabled:YES];
- }
-
- // Remove the bookmark with the long title.
- void RemoveLongTitleNode() {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- model->Remove(longTitleNode_->GetParent(),
- longTitleNode_->GetParent()->IndexOfChild(longTitleNode_));
- }
-
- // Add LOTS of nodes to our model if needed (e.g. scrolling).
- // Returns the number of nodes added.
- int AddLotsOfNodes() {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- for (int i = 0; i < kLotsOfNodesCount; i++) {
- model->AddURL(folderA_, folderA_->GetChildCount(),
- ASCIIToUTF16("repeated title"),
- GURL("http://www.google.com/repeated/url"));
- }
- return kLotsOfNodesCount;
- }
-
- // Return a simple BookmarkBarFolderController.
- BookmarkBarFolderControllerPong* SimpleBookmarkBarFolderController() {
- BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0];
- BookmarkBarFolderControllerPong* c =
- [[BookmarkBarFolderControllerPong alloc]
- initWithParentButton:parentButton
- parentController:nil
- barController:bar_];
- [c window]; // Force nib load.
- return c;
- }
-};
-
-TEST_F(BookmarkBarFolderControllerTest, InitCreateAndDelete) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
- bbfc.reset(SimpleBookmarkBarFolderController());
-
- // Make sure none of the buttons overlap, that all are inside
- // the content frame, and their cells are of the proper class.
- NSArray* buttons = [bbfc buttons];
- EXPECT_TRUE([buttons count]);
- for (unsigned int i = 0; i < ([buttons count]-1); i++) {
- EXPECT_FALSE(NSContainsRect([[buttons objectAtIndex:i] frame],
- [[buttons objectAtIndex:i+1] frame]));
- }
- Class cellClass = [BookmarkBarFolderButtonCell class];
- for (BookmarkButton* button in buttons) {
- NSRect r = [[bbfc mainView] convertRect:[button frame] fromView:button];
- // TODO(jrg): remove this adjustment.
- NSRect bigger = NSInsetRect([[bbfc mainView] frame], -2, 0);
- EXPECT_TRUE(NSContainsRect(bigger, r));
- EXPECT_TRUE([[button cell] isKindOfClass:cellClass]);
- }
-
- // Confirm folder buttons have no tooltip. The important thing
- // really is that we insure folders and non-folders are treated
- // differently; not sure of any other generic way to do this.
- for (BookmarkButton* button in buttons) {
- if ([button isFolder])
- EXPECT_FALSE([button toolTip]);
- else
- EXPECT_TRUE([button toolTip]);
- }
-}
-
-// Make sure closing of the window releases the controller.
-// (e.g. valgrind shouldn't complain if we do this).
-TEST_F(BookmarkBarFolderControllerTest, ReleaseOnClose) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
-
- [bbfc retain]; // stop the scoped_nsobject from doing anything
- [[bbfc window] close]; // trigger an autorelease of bbfc.get()
-}
-
-TEST_F(BookmarkBarFolderControllerTest, BasicPosition) {
- BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0];
- EXPECT_TRUE(parentButton);
-
- // If parent is a BookmarkBarController, grow down.
- scoped_nsobject<BookmarkBarFolderControllerLow> bbfc;
- bbfc.reset([[BookmarkBarFolderControllerLow alloc]
- initWithParentButton:parentButton
- parentController:nil
- barController:bar_]);
- [bbfc window];
- [bbfc setRealTopLeft:YES];
- NSPoint pt = [bbfc windowTopLeftForWidth:0]; // screen coords
- NSPoint buttonOriginInScreen =
- [[parentButton window]
- convertBaseToScreen:[parentButton
- convertRectToBase:[parentButton frame]].origin];
- // Within margin
- EXPECT_LE(abs(pt.x - buttonOriginInScreen.x),
- bookmarks::kBookmarkMenuOverlap+1);
- EXPECT_LE(abs(pt.y - buttonOriginInScreen.y),
- bookmarks::kBookmarkMenuOverlap+1);
-
- // Make sure we see the window shift left if it spills off the screen
- pt = [bbfc windowTopLeftForWidth:0];
- NSPoint shifted = [bbfc windowTopLeftForWidth:9999999];
- EXPECT_LT(shifted.x, pt.x);
-
- // If parent is a BookmarkBarFolderController, grow right.
- scoped_nsobject<BookmarkBarFolderControllerLow> bbfc2;
- bbfc2.reset([[BookmarkBarFolderControllerLow alloc]
- initWithParentButton:[[bbfc buttons] objectAtIndex:0]
- parentController:bbfc.get()
- barController:bar_]);
- [bbfc2 window];
- [bbfc2 setRealTopLeft:YES];
- pt = [bbfc2 windowTopLeftForWidth:0];
- // We're now overlapping the window a bit.
- EXPECT_EQ(pt.x, NSMaxX([[bbfc.get() window] frame]) -
- bookmarks::kBookmarkMenuOverlap);
-}
-
-// Confirm we grow right until end of screen, then start growing left
-// until end of screen again, then right.
-TEST_F(BookmarkBarFolderControllerTest, PositionRightLeftRight) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = parent;
-
- const int count = 100;
- int i;
- // Make some super duper deeply nested folders.
- for (i=0; i<count; i++) {
- folder = model->AddGroup(folder, 0, ASCIIToUTF16("nested folder"));
- }
-
- // Setup initial state for opening all folders.
- folder = parent;
- BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0];
- BookmarkBarFolderController* parentController = nil;
- EXPECT_TRUE(parentButton);
-
- // Open them all.
- scoped_nsobject<NSMutableArray> folder_controller_array;
- folder_controller_array.reset([[NSMutableArray array] retain]);
- for (i=0; i<count; i++) {
- BookmarkBarFolderControllerNoLevel* bbfcl =
- [[BookmarkBarFolderControllerNoLevel alloc]
- initWithParentButton:parentButton
- parentController:parentController
- barController:bar_];
- [folder_controller_array addObject:bbfcl];
- [bbfcl autorelease];
- [bbfcl window];
- parentController = bbfcl;
- parentButton = [[bbfcl buttons] objectAtIndex:0];
- }
-
- // Make vector of all x positions.
- std::vector<CGFloat> leftPositions;
- for (i=0; i<count; i++) {
- CGFloat x = [[[folder_controller_array objectAtIndex:i] window]
- frame].origin.x;
- leftPositions.push_back(x);
- }
-
- // Make sure the first few grow right.
- for (i=0; i<3; i++)
- EXPECT_TRUE(leftPositions[i+1] > leftPositions[i]);
-
- // Look for the first "grow left".
- while (leftPositions[i] > leftPositions[i-1])
- i++;
- // Confirm the next few also grow left.
- int j;
- for (j=i; j<i+3; j++)
- EXPECT_TRUE(leftPositions[j+1] < leftPositions[j]);
- i = j;
-
- // Finally, confirm we see a "grow right" once more.
- while (leftPositions[i] < leftPositions[i-1])
- i++;
- // (No need to EXPECT a final "grow right"; if we didn't find one
- // we'd get a C++ array bounds exception).
-}
-
-TEST_F(BookmarkBarFolderControllerTest, DropDestination) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
-
- // Confirm "off the top" and "off the bottom" match no buttons.
- NSPoint p = NSMakePoint(NSMidX([[bbfc mainView] frame]), 10000);
- EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:p]);
- EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:p]);
- p = NSMakePoint(NSMidX([[bbfc mainView] frame]), -1);
- EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:p]);
- EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:p]);
-
- // Confirm "right in the center" (give or take a pixel) is a match,
- // and confirm "just barely in the button" is not. Anything more
- // specific seems likely to be tweaked. We don't loop over all
- // buttons because the scroll view makes them not visible.
- for (BookmarkButton* button in [bbfc buttons]) {
- CGFloat x = NSMidX([button frame]);
- CGFloat y = NSMidY([button frame]);
- // Somewhere near the center: a match (but only if a folder!)
- if ([button isFolder]) {
- EXPECT_EQ(button,
- [bbfc buttonForDroppingOnAtPoint:NSMakePoint(x-1, y+1)]);
- EXPECT_EQ(button,
- [bbfc buttonForDroppingOnAtPoint:NSMakePoint(x+1, y-1)]);
- EXPECT_FALSE([bbfc shouldShowIndicatorShownForPoint:NSMakePoint(x, y)]);;
- } else {
- // If not a folder we don't drop into it.
- EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:NSMakePoint(x-1, y+1)]);
- EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:NSMakePoint(x+1, y-1)]);
- EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:NSMakePoint(x, y)]);;
- }
- }
-}
-
-TEST_F(BookmarkBarFolderControllerTest, OpenFolder) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
-
- EXPECT_FALSE([bbfc folderController]);
- BookmarkButton* button = [[bbfc buttons] objectAtIndex:0];
- [bbfc openBookmarkFolderFromButton:button];
- id controller = [bbfc folderController];
- EXPECT_TRUE(controller);
- EXPECT_EQ([controller parentButton], button);
-
- // Click the same one --> it gets closed.
- [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:0]];
- EXPECT_FALSE([bbfc folderController]);
-
- // Open a new one --> change.
- [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:1]];
- EXPECT_NE(controller, [bbfc folderController]);
- EXPECT_NE([[bbfc folderController] parentButton], button);
-
- // Close it --> all gone!
- [bbfc closeBookmarkFolder:nil];
- EXPECT_FALSE([bbfc folderController]);
-}
-
-TEST_F(BookmarkBarFolderControllerTest, ChildFolderCallbacks) {
- scoped_nsobject<BookmarkBarFolderControllerPong> bbfc;
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
- [bar_ setChildFolderDelegate:bbfc.get()];
-
- EXPECT_FALSE([bbfc childFolderWillShow]);
- [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:0]];
- EXPECT_TRUE([bbfc childFolderWillShow]);
-
- EXPECT_FALSE([bbfc childFolderWillClose]);
- [bbfc closeBookmarkFolder:nil];
- EXPECT_TRUE([bbfc childFolderWillClose]);
-
- [bar_ setChildFolderDelegate:nil];
-}
-
-// Make sure bookmark folders have variable widths.
-TEST_F(BookmarkBarFolderControllerTest, ChildFolderWidth) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
-
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
- [bbfc showWindow:bbfc.get()];
- CGFloat wideWidth = NSWidth([[bbfc window] frame]);
-
- RemoveLongTitleNode();
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
- CGFloat thinWidth = NSWidth([[bbfc window] frame]);
-
- // Make sure window size changed as expected.
- EXPECT_GT(wideWidth, thinWidth);
-}
-
-// Simple scrolling tests.
-TEST_F(BookmarkBarFolderControllerTest, SimpleScroll) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
-
- int nodecount = AddLotsOfNodes();
- bbfc.reset(SimpleBookmarkBarFolderController());
- EXPECT_TRUE(bbfc.get());
- [bbfc showWindow:bbfc.get()];
-
- // Make sure the window fits on the screen.
- EXPECT_LT(NSHeight([[bbfc window] frame]),
- NSHeight([[NSScreen mainScreen] frame]));
-
- // Verify the logic used by the scroll arrow code.
- EXPECT_TRUE([bbfc canScrollUp]);
- EXPECT_FALSE([bbfc canScrollDown]);
-
- // Scroll it up. Make sure the window has gotten bigger each time.
- // Also, for each scroll, make sure our hit test finds a new button
- // (to confirm the content area changed).
- NSView* savedHit = nil;
- for (int i=0; i<3; i++) {
- CGFloat height = NSHeight([[bbfc window] frame]);
- [bbfc performOneScroll:60];
- EXPECT_GT(NSHeight([[bbfc window] frame]), height);
- NSView* hit = [[[bbfc window] contentView] hitTest:NSMakePoint(22, 22)];
- EXPECT_NE(hit, savedHit);
- savedHit = hit;
- }
-
- // Keep scrolling up; make sure we never get bigger than the screen.
- // Also confirm we never scroll the window off the screen.
- bool bothAtOnce = false;
- NSRect screenFrame = [[NSScreen mainScreen] frame];
- for (int i = 0; i < nodecount; i++) {
- [bbfc performOneScroll:60];
- EXPECT_TRUE(NSContainsRect(screenFrame,
- [[bbfc window] frame]));
- // Make sure, sometime during our scroll, we have the ability to
- // scroll in either direction.
- if ([bbfc canScrollUp] &&
- [bbfc canScrollDown])
- bothAtOnce = true;
- }
- EXPECT_TRUE(bothAtOnce);
-
- // Once we've scrolled to the end, our only option should be to scroll back.
- EXPECT_FALSE([bbfc canScrollUp]);
- EXPECT_TRUE([bbfc canScrollDown]);
-
- // Now scroll down and make sure the window size does not change.
- // Also confirm we never scroll the window off the screen the other
- // way.
- for (int i=0; i<nodecount+50; i++) {
- CGFloat height = NSHeight([[bbfc window] frame]);
- [bbfc performOneScroll:-60];
- EXPECT_EQ(height, NSHeight([[bbfc window] frame]));
- EXPECT_TRUE(NSContainsRect(screenFrame,
- [[bbfc window] frame]));
- }
-}
-
-// Folder menu sizing and placementwhile deleting bookmarks and scrolling tests.
-TEST_F(BookmarkBarFolderControllerTest, MenuPlacementWhileScrollingDeleting) {
- scoped_nsobject<BookmarkBarFolderController> bbfc;
- AddLotsOfNodes();
- bbfc.reset(SimpleBookmarkBarFolderController());
- [bbfc showWindow:bbfc.get()];
- NSWindow* menuWindow = [bbfc window];
- BookmarkBarFolderController* folder = [bar_ folderController];
- NSArray* buttons = [folder buttons];
-
- // Before scrolling any, delete a bookmark and make sure the window top has
- // not moved. Pick a button which is near the top and visible.
- CGFloat oldTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]);
- BookmarkButton* button = [buttons objectAtIndex:3];
- [folder deleteBookmark:button];
- CGFloat newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]);
- EXPECT_CGFLOAT_EQ(oldTop, newTop);
-
- // Scroll so that both the top and bottom scroll arrows show, make sure
- // the top of the window has moved up, then delete a visible button and
- // make sure the top has not moved.
- oldTop = newTop;
- const CGFloat scrollOneBookmark = bookmarks::kBookmarkButtonHeight +
- bookmarks::kBookmarkVerticalPadding;
- NSUInteger buttonCounter = 0;
- NSUInteger extraButtonLimit = 3;
- while (![bbfc canScrollDown] || extraButtonLimit > 0) {
- [bbfc performOneScroll:scrollOneBookmark];
- ++buttonCounter;
- if ([bbfc canScrollDown])
- --extraButtonLimit;
- }
- newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]);
- EXPECT_NE(oldTop, newTop);
- oldTop = newTop;
- button = [buttons objectAtIndex:buttonCounter + 3];
- [folder deleteBookmark:button];
- newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]);
- EXPECT_CGFLOAT_EQ(oldTop, newTop);
-
- // Scroll so that the top scroll arrow is no longer showing, make sure
- // the top of the window has not moved, then delete a visible button and
- // make sure the top has not moved.
- while ([bbfc canScrollDown]) {
- [bbfc performOneScroll:-scrollOneBookmark];
- --buttonCounter;
- }
- button = [buttons objectAtIndex:buttonCounter + 3];
- [folder deleteBookmark:button];
- newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]);
- EXPECT_CGFLOAT_EQ(oldTop, newTop);
-}
-
-@interface FakedDragInfo : NSObject {
-@public
- NSPoint dropLocation_;
- NSDragOperation sourceMask_;
-}
-@property (nonatomic, assign) NSPoint dropLocation;
-- (void)setDraggingSourceOperationMask:(NSDragOperation)mask;
-@end
-
-@implementation FakedDragInfo
-
-@synthesize dropLocation = dropLocation_;
-
-- (id)init {
- if ((self = [super init])) {
- dropLocation_ = NSZeroPoint;
- sourceMask_ = NSDragOperationMove;
- }
- return self;
-}
-
-// NSDraggingInfo protocol functions.
-
-- (id)draggingPasteboard {
- return self;
-}
-
-- (id)draggingSource {
- return self;
-}
-
-- (NSDragOperation)draggingSourceOperationMask {
- return sourceMask_;
-}
-
-- (NSPoint)draggingLocation {
- return dropLocation_;
-}
-
-// Other functions.
-
-- (void)setDraggingSourceOperationMask:(NSDragOperation)mask {
- sourceMask_ = mask;
-}
-
-@end
-
-
-class BookmarkBarFolderControllerMenuTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
- scoped_nsobject<NSView> parent_view_;
- scoped_nsobject<ViewResizerPong> resizeDelegate_;
- scoped_nsobject<BookmarkBarController> bar_;
-
- BookmarkBarFolderControllerMenuTest() {
- resizeDelegate_.reset([[ViewResizerPong alloc] init]);
- NSRect parent_frame = NSMakeRect(0, 0, 800, 50);
- parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]);
- [parent_view_ setHidden:YES];
- bar_.reset([[BookmarkBarController alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth(parent_frame)
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
- InstallAndToggleBar(bar_.get());
- }
-
- void InstallAndToggleBar(BookmarkBarController* bar) {
- // Force loading of the nib.
- [bar view];
- // Awkwardness to look like we've been installed.
- [parent_view_ addSubview:[bar view]];
- NSRect frame = [[[bar view] superview] frame];
- frame.origin.y = 100;
- [[[bar view] superview] setFrame:frame];
-
- // Make sure it's on in a window so viewDidMoveToWindow is called
- [[test_window() contentView] addSubview:parent_view_];
-
- // Make sure it's open so certain things aren't no-ops.
- [bar updateAndShowNormalBar:YES
- showDetachedBar:NO
- withAnimation:NO];
- }
-};
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToFolder) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu and drag in a button from the bar.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"];
- NSRect oldToFolderFrame = [toFolder frame];
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- NSRect oldToWindowFrame = [toWindow frame];
- // Drag a bar button onto a bookmark (i.e. not a folder) in a folder
- // so it should end up below the target bookmark.
- BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"1b"];
- ASSERT_TRUE(draggedButton);
- CGFloat horizontalShift =
- NSWidth([draggedButton frame]) + bookmarks::kBookmarkHorizontalPadding;
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton center]
- copy:NO];
- // The button should have landed just after "2f1b".
- const std::string expected_string("2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
- "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root));
-
- // Verify the window still appears by looking for its controller.
- EXPECT_TRUE([bar_ folderController]);
-
- // Gather the new frames.
- NSRect newToFolderFrame = [toFolder frame];
- NSRect newToWindowFrame = [toWindow frame];
- // The toFolder should have shifted left horizontally but not vertically.
- NSRect expectedToFolderFrame =
- NSOffsetRect(oldToFolderFrame, -horizontalShift, 0);
- EXPECT_NSRECT_EQ(expectedToFolderFrame, newToFolderFrame);
- // The toWindow should have shifted left horizontally, down vertically,
- // and grown vertically.
- NSRect expectedToWindowFrame = oldToWindowFrame;
- expectedToWindowFrame.origin.x -= horizontalShift;
- CGFloat diff = (bookmarks::kBookmarkBarHeight +
- 2*bookmarks::kBookmarkVerticalPadding);
- expectedToWindowFrame.origin.y -= diff;
- expectedToWindowFrame.size.height += diff;
- EXPECT_NSRECT_EQ(expectedToWindowFrame, newToWindowFrame);
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-
- // Move the button back to the bar at the beginning.
- draggedButton = [folderController buttonWithTitleEqualTo:@"1b"];
- ASSERT_TRUE(draggedButton);
- targetButton = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(targetButton);
- [bar_ dragButton:draggedButton
- to:[targetButton left]
- copy:NO];
- EXPECT_EQ(model_string, model_test_utils::ModelStringFromNode(root));
- // Don't check the folder window since it's not supposed to be showing.
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragCopyBarBookmarkToFolder) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu and copy in a button from the bar.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(toFolder);
- NSRect oldToFolderFrame = [toFolder frame];
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- NSRect oldToWindowFrame = [toWindow frame];
- // Drag a bar button onto a bookmark (i.e. not a folder) in a folder
- // so it should end up below the target bookmark.
- BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"1b"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton center]
- copy:YES];
- // The button should have landed just after "2f1b".
- const std::string expected_1("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
- "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- EXPECT_EQ(expected_1, model_test_utils::ModelStringFromNode(root));
-
- // Gather the new frames.
- NSRect newToFolderFrame = [toFolder frame];
- NSRect newToWindowFrame = [toWindow frame];
- // The toFolder should have shifted.
- EXPECT_NSRECT_EQ(oldToFolderFrame, newToFolderFrame);
- // The toWindow should have shifted down vertically and grown vertically.
- NSRect expectedToWindowFrame = oldToWindowFrame;
- CGFloat diff = (bookmarks::kBookmarkBarHeight +
- 2*bookmarks::kBookmarkVerticalPadding);
- expectedToWindowFrame.origin.y -= diff;
- expectedToWindowFrame.size.height += diff;
- EXPECT_NSRECT_EQ(expectedToWindowFrame, newToWindowFrame);
-
- // Copy the button back to the bar after "3b".
- draggedButton = [folderController buttonWithTitleEqualTo:@"1b"];
- ASSERT_TRUE(draggedButton);
- targetButton = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(targetButton);
- [bar_ dragButton:draggedButton
- to:[targetButton left]
- copy:YES];
- const std::string expected_2("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 1b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
- "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- EXPECT_EQ(expected_2, model_test_utils::ModelStringFromNode(root));
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToSubfolder) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu and a subfolder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- NSRect oldToWindowFrame = [toWindow frame];
- BookmarkButton* toSubfolder =
- [folderController buttonWithTitleEqualTo:@"4f2f"];
- ASSERT_TRUE(toSubfolder);
- [[toSubfolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toSubfolder];
- BookmarkBarFolderController* subfolderController =
- [folderController folderController];
- EXPECT_TRUE(subfolderController);
- NSWindow* toSubwindow = [subfolderController window];
- EXPECT_TRUE(toSubwindow);
- NSRect oldToSubwindowFrame = [toSubwindow frame];
- // Drag a bar button onto a bookmark (i.e. not a folder) in a folder
- // so it should end up below the target bookmark.
- BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"5b"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [subfolderController buttonWithTitleEqualTo:@"4f2f3b"];
- ASSERT_TRUE(targetButton);
- [subfolderController dragButton:draggedButton
- to:[targetButton center]
- copy:NO];
- // The button should have landed just after "2f".
- const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ "
- "4f2f1b 4f2f2b 4f2f3b 5b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] ");
- EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root));
-
- // Check button spacing.
- [folderController validateMenuSpacing];
- [subfolderController validateMenuSpacing];
-
- // Check the window layouts. The folder window should not have changed,
- // but the subfolder window should have shifted vertically and grown.
- NSRect newToWindowFrame = [toWindow frame];
- EXPECT_NSRECT_EQ(oldToWindowFrame, newToWindowFrame);
- NSRect newToSubwindowFrame = [toSubwindow frame];
- NSRect expectedToSubwindowFrame = oldToSubwindowFrame;
- expectedToSubwindowFrame.origin.y -=
- bookmarks::kBookmarkBarHeight + bookmarks::kVisualHeightOffset;
- expectedToSubwindowFrame.size.height +=
- bookmarks::kBookmarkBarHeight + bookmarks::kVisualHeightOffset;
- EXPECT_NSRECT_EQ(expectedToSubwindowFrame, newToSubwindowFrame);
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveWithinFolder) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- NSRect oldToWindowFrame = [toWindow frame];
- // Drag a folder button to the top within the same parent.
- BookmarkButton* draggedButton =
- [folderController buttonWithTitleEqualTo:@"4f2f"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"4f1f"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton top]
- copy:NO];
- // The button should have landed above "4f1f".
- const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f2f:[ 4f2f1b 4f2f2b 4f2f3b ] "
- "4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root));
-
- // The window should not have gone away.
- EXPECT_TRUE([bar_ folderController]);
-
- // The folder window should not have changed.
- NSRect newToWindowFrame = [toWindow frame];
- EXPECT_NSRECT_EQ(oldToWindowFrame, newToWindowFrame);
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragParentOntoChild) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- // Drag a folder button to one of its children.
- BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"4f3f"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton top]
- copy:NO];
- // The model should not have changed.
- EXPECT_EQ(model_string, model_test_utils::ModelStringFromNode(root));
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveChildToParent) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b "
- "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu and a subfolder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- BookmarkButton* toSubfolder =
- [folderController buttonWithTitleEqualTo:@"4f2f"];
- ASSERT_TRUE(toSubfolder);
- [[toSubfolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toSubfolder];
- BookmarkBarFolderController* subfolderController =
- [folderController folderController];
- EXPECT_TRUE(subfolderController);
-
- // Drag a subfolder bookmark to the parent folder.
- BookmarkButton* draggedButton =
- [subfolderController buttonWithTitleEqualTo:@"4f2f3b"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"4f2f"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton top]
- copy:NO];
- // The button should have landed above "4f2f".
- const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f3b 4f2f:[ "
- "4f2f1b 4f2f2b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b ");
- EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root));
-
- // Check button spacing.
- [folderController validateMenuSpacing];
- // The window should not have gone away.
- EXPECT_TRUE([bar_ folderController]);
- // The subfolder should have gone away.
- EXPECT_FALSE([folderController folderController]);
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragWindowResizing) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string
- model_string("a b:[ b1 b2 b3 ] reallyReallyLongBookmarkName c ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"b"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* toWindow = [folderController window];
- EXPECT_TRUE(toWindow);
- CGFloat oldWidth = NSWidth([toWindow frame]);
- // Drag the bookmark with a long name to the folder.
- BookmarkButton* draggedButton =
- [bar_ buttonWithTitleEqualTo:@"reallyReallyLongBookmarkName"];
- ASSERT_TRUE(draggedButton);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"b1"];
- ASSERT_TRUE(targetButton);
- [folderController dragButton:draggedButton
- to:[targetButton center]
- copy:NO];
- // Verify the model change.
- const std::string
- expected_string("a b:[ b1 reallyReallyLongBookmarkName b2 b3 ] c ");
- EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root));
- // Verify the window grew. Just test a reasonable width gain.
- CGFloat newWidth = NSWidth([toWindow frame]);
- EXPECT_LT(oldWidth + 30.0, newWidth);
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, MoveRemoveAddButtons) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b 2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Pop up a folder menu.
- BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(toFolder);
- [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:toFolder];
- BookmarkBarFolderController* folder = [bar_ folderController];
- EXPECT_TRUE(folder);
-
- // Remember how many buttons are showing.
- NSArray* buttons = [folder buttons];
- NSUInteger oldDisplayedButtons = [buttons count];
-
- // Move a button around a bit.
- [folder moveButtonFromIndex:0 toIndex:2];
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [buttons count]);
- [folder moveButtonFromIndex:2 toIndex:0];
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [buttons count]);
-
- // Add a couple of buttons.
- const BookmarkNode* node = root->GetChild(2); // Purloin an existing node.
- [folder addButtonForNode:node atIndex:0];
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:2] title]);
- EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:3] title]);
- EXPECT_EQ(oldDisplayedButtons + 1, [buttons count]);
- node = root->GetChild(3);
- [folder addButtonForNode:node atIndex:-1];
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:2] title]);
- EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:3] title]);
- EXPECT_NSEQ(@"4b", [[buttons objectAtIndex:4] title]);
- EXPECT_EQ(oldDisplayedButtons + 2, [buttons count]);
-
- // Remove a couple of buttons.
- [folder removeButton:4 animate:NO];
- [folder removeButton:1 animate:NO];
- EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]);
- EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:1] title]);
- EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:2] title]);
- EXPECT_EQ(oldDisplayedButtons, [buttons count]);
-
- // Check button spacing.
- [folder validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, ControllerForNode) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Find the main bar controller.
- const void* expectedController = bar_;
- const void* actualController = [bar_ controllerForNode:root];
- EXPECT_EQ(expectedController, actualController);
-
- // Pop up the folder menu.
- BookmarkButton* targetFolder = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(targetFolder);
- [[targetFolder target]
- performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:targetFolder];
- BookmarkBarFolderController* folder = [bar_ folderController];
- EXPECT_TRUE(folder);
-
- // Find the folder controller using the folder controller.
- const BookmarkNode* targetNode = root->GetChild(1);
- expectedController = folder;
- actualController = [bar_ controllerForNode:targetNode];
- EXPECT_EQ(expectedController, actualController);
-
- // Find the folder controller from the bar.
- actualController = [folder controllerForNode:targetNode];
- EXPECT_EQ(expectedController, actualController);
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2b 3b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- const BookmarkNode* parent = model.GetBookmarkBarNode();
- const BookmarkNode* folder = model.AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("BIG"));
-
- // Pop open the new folder window and verify it has one (empty) item.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"BIG"];
- [[button target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:button];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSWindow* folderMenu = [folderController window];
- EXPECT_TRUE(folderMenu);
- CGFloat expectedHeight = (CGFloat)bookmarks::kBookmarkButtonHeight +
- (2*bookmarks::kBookmarkVerticalPadding);
- NSRect menuFrame = [folderMenu frame];
- CGFloat menuHeight = NSHeight(menuFrame);
- EXPECT_CGFLOAT_EQ(expectedHeight, menuHeight);
- EXPECT_FALSE([folderController scrollable]);
-
- // Now add a real bookmark and reopen.
- model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("a"),
- GURL("http://a.com/"));
- folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- folderMenu = [folderController window];
- EXPECT_TRUE(folderMenu);
- menuFrame = [folderMenu frame];
- menuHeight = NSHeight(menuFrame);
- EXPECT_CGFLOAT_EQ(expectedHeight, menuHeight);
- CGFloat menuWidth = NSWidth(menuFrame);
- button = [folderController buttonWithTitleEqualTo:@"a"];
- CGFloat buttonWidth = NSWidth([button frame]);
- CGFloat expectedWidth =
- buttonWidth + (2 * bookmarks::kBookmarkSubMenuHorizontalPadding);
- EXPECT_CGFLOAT_EQ(expectedWidth, menuWidth);
-
- // Add a wider bookmark and make sure the button widths match.
- model.AddURL(folder, folder->GetChildCount(),
- ASCIIToUTF16("A really, really long name"),
- GURL("http://www.google.com/a"));
- EXPECT_LT(menuWidth, NSWidth([folderMenu frame]));
- EXPECT_LT(buttonWidth, NSWidth([button frame]));
- buttonWidth = NSWidth([button frame]);
- BookmarkButton* buttonB =
- [folderController buttonWithTitleEqualTo:@"A really, really long name"];
- EXPECT_TRUE(buttonB);
- CGFloat buttonWidthB = NSWidth([buttonB frame]);
- EXPECT_CGFLOAT_EQ(buttonWidth, buttonWidthB);
- // Add a bunch of bookmarks until the window grows no more, then check for
- // a scroll down arrow.
- CGFloat oldMenuHeight = 0.0; // It just has to be different for first run.
- menuHeight = NSHeight([folderMenu frame]);
- NSUInteger tripWire = 0; // Prevent a runaway.
- while (![folderController scrollable] && ++tripWire < 100) {
- model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("B"),
- GURL("http://b.com/"));
- oldMenuHeight = menuHeight;
- menuHeight = NSHeight([folderMenu frame]);
- }
- EXPECT_TRUE([folderController scrollable]);
- EXPECT_TRUE([folderController canScrollUp]);
-
- // Remove one bookmark and make sure the scroll down arrow has been removed.
- // We'll remove the really long node so we can see if the buttons get resized.
- menuWidth = NSWidth([folderMenu frame]);
- buttonWidth = NSWidth([button frame]);
- model.Remove(folder, 1);
- EXPECT_FALSE([folderController scrollable]);
- EXPECT_FALSE([folderController canScrollUp]);
- EXPECT_FALSE([folderController canScrollDown]);
-
- // Check the size. It should have reduced.
- EXPECT_GT(menuWidth, NSWidth([folderMenu frame]));
- EXPECT_GT(buttonWidth, NSWidth([button frame]));
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-// See http://crbug.com/46101
-TEST_F(BookmarkBarFolderControllerMenuTest, HoverThenDeleteBookmark) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const BookmarkNode* folder = model.AddGroup(root,
- root->GetChildCount(),
- ASCIIToUTF16("BIG"));
- for (int i = 0; i < kLotsOfNodesCount; i++)
- model.AddURL(folder, folder->GetChildCount(), ASCIIToUTF16("kid"),
- GURL("http://kid.com/smile"));
-
- // Pop open the new folder window and hover one of its kids.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"BIG"];
- [[button target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:button];
- BookmarkBarFolderController* bbfc = [bar_ folderController];
- NSArray* buttons = [bbfc buttons];
-
- // Hover over a button and verify that it is now known.
- button = [buttons objectAtIndex:3];
- BookmarkButton* buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn];
- EXPECT_FALSE(buttonThatMouseIsIn);
- [bbfc mouseEnteredButton:button event:nil];
- buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn];
- EXPECT_EQ(button, buttonThatMouseIsIn);
-
- // Delete the bookmark and verify that it is now not known.
- model.Remove(folder, 3);
- buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn];
- EXPECT_FALSE(buttonThatMouseIsIn);
-}
-
-// Just like a BookmarkBarFolderController but intercedes when providing
-// pasteboard drag data.
-@interface BookmarkBarFolderControllerDragData : BookmarkBarFolderController {
- const BookmarkNode* dragDataNode_; // Weak
-}
-- (void)setDragDataNode:(const BookmarkNode*)node;
-@end
-
-@implementation BookmarkBarFolderControllerDragData
-
-- (id)initWithParentButton:(BookmarkButton*)button
- parentController:(BookmarkBarFolderController*)parentController
- barController:(BookmarkBarController*)barController {
- if ((self = [super initWithParentButton:button
- parentController:parentController
- barController:barController])) {
- dragDataNode_ = NULL;
- }
- return self;
-}
-
-- (void)setDragDataNode:(const BookmarkNode*)node {
- dragDataNode_ = node;
-}
-
-- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData {
- std::vector<const BookmarkNode*> dragDataNodes;
- if(dragDataNode_) {
- dragDataNodes.push_back(dragDataNode_);
- }
- return dragDataNodes;
-}
-
-@end
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkData) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
- const BookmarkNode* other = model.other_node();
- const std::string other_string("O1b O2b O3f:[ O3f1b O3f2f ] "
- "O4f:[ O4f1b O4f2f ] 05b ");
- model_test_utils::AddNodesFromModelString(model, other, other_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
- actual = model_test_utils::ModelStringFromNode(other);
- EXPECT_EQ(other_string, actual);
-
- // Pop open a folder.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"];
- scoped_nsobject<BookmarkBarFolderControllerDragData> folderController;
- folderController.reset([[BookmarkBarFolderControllerDragData alloc]
- initWithParentButton:button
- parentController:nil
- barController:bar_]);
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(targetButton);
-
- // Gen up some dragging data.
- const BookmarkNode* newNode = other->GetChild(2);
- [folderController setDragDataNode:newNode];
- scoped_nsobject<FakedDragInfo> dragInfo([[FakedDragInfo alloc] init]);
- [dragInfo setDropLocation:[targetButton top]];
- [folderController dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()];
-
- // Verify the model.
- const std::string expected("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ 2f2f1b "
- "2f2f2b 2f2f3b ] 2f3b ] 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
-
- // Now drag over a folder button.
- targetButton = [folderController buttonWithTitleEqualTo:@"2f2f"];
- ASSERT_TRUE(targetButton);
- newNode = other->GetChild(2); // Should be O4f.
- EXPECT_EQ(newNode->GetTitle(), ASCIIToUTF16("O4f"));
- [folderController setDragDataNode:newNode];
- [dragInfo setDropLocation:[targetButton center]];
- [folderController dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()];
-
- // Verify the model.
- const std::string expectedA("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ "
- "2f2f1b 2f2f2b 2f2f3b O4f:[ O4f1b O4f2f ] ] "
- "2f3b ] 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expectedA, actual);
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
-
- const BookmarkNode* folderNode = root->GetChild(1);
- int oldFolderChildCount = folderNode->GetChildCount();
-
- // Pop open a folder.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"];
- scoped_nsobject<BookmarkBarFolderControllerDragData> folderController;
- folderController.reset([[BookmarkBarFolderControllerDragData alloc]
- initWithParentButton:button
- parentController:nil
- barController:bar_]);
-
- // Drag a button to the trash.
- BookmarkButton* buttonToDelete =
- [folderController buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(buttonToDelete);
- EXPECT_TRUE([folderController canDragBookmarkButtonToTrash:buttonToDelete]);
- [folderController didDragBookmarkToTrash:buttonToDelete];
-
- // There should be one less button in the folder.
- int newFolderChildCount = folderNode->GetChildCount();
- EXPECT_EQ(oldFolderChildCount - 1, newFolderChildCount);
- // Verify the model.
- const std::string expected("1b 2f:[ 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, AddURLs) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
-
- // Pop open a folder.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"];
- [[button target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:button];
- BookmarkBarFolderController* folderController = [bar_ folderController];
- EXPECT_TRUE(folderController);
- NSArray* buttons = [folderController buttons];
- EXPECT_TRUE(buttons);
-
- // Remember how many buttons are showing.
- int oldDisplayedButtons = [buttons count];
-
- BookmarkButton* targetButton =
- [folderController buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(targetButton);
-
- NSArray* urls = [NSArray arrayWithObjects: @"http://www.a.com/",
- @"http://www.b.com/", nil];
- NSArray* titles = [NSArray arrayWithObjects: @"SiteA", @"SiteB", nil];
- [folderController addURLs:urls withTitles:titles at:[targetButton top]];
-
- // There should two more buttons in the folder.
- int newDisplayedButtons = [buttons count];
- EXPECT_EQ(oldDisplayedButtons + 2, newDisplayedButtons);
- // Verify the model.
- const std::string expected("1b 2f:[ SiteA SiteB 2f1b 2f2f:[ 2f2f1b 2f2f2b "
- "2f2f3b ] 2f3b ] 3b 4b ");
- actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(expected, actual);
-
- // Check button spacing.
- [folderController validateMenuSpacing];
-}
-
-TEST_F(BookmarkBarFolderControllerMenuTest, DropPositionIndicator) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] "
- "2f3b ] 3b 4b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actual = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actual);
-
- // Pop open the folder.
- BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"];
- [[button target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:button];
- BookmarkBarFolderController* folder = [bar_ folderController];
- EXPECT_TRUE(folder);
-
- // Test a series of points starting at the top of the folder.
- const CGFloat yOffset = 0.5 * bookmarks::kBookmarkVerticalPadding;
- BookmarkButton* targetButton = [folder buttonWithTitleEqualTo:@"2f1b"];
- ASSERT_TRUE(targetButton);
- NSPoint targetPoint = [targetButton top];
- CGFloat pos = [folder indicatorPosForDragToPoint:targetPoint];
- EXPECT_CGFLOAT_EQ(targetPoint.y + yOffset, pos);
- pos = [folder indicatorPosForDragToPoint:[targetButton bottom]];
- targetButton = [folder buttonWithTitleEqualTo:@"2f2f"];
- EXPECT_CGFLOAT_EQ([targetButton top].y + yOffset, pos);
- pos = [folder indicatorPosForDragToPoint:NSMakePoint(10,0)];
- targetButton = [folder buttonWithTitleEqualTo:@"2f3b"];
- EXPECT_CGFLOAT_EQ([targetButton bottom].y - yOffset, pos);
-}
-
-@interface BookmarkBarControllerNoDelete : BookmarkBarController
-- (IBAction)deleteBookmark:(id)sender;
-@end
-
-@implementation BookmarkBarControllerNoDelete
-- (IBAction)deleteBookmark:(id)sender {
- // NOP
-}
-@end
-
-class BookmarkBarFolderControllerClosingTest : public
- BookmarkBarFolderControllerMenuTest {
- public:
- BookmarkBarFolderControllerClosingTest() {
- bar_.reset([[BookmarkBarControllerNoDelete alloc]
- initWithBrowser:helper_.browser()
- initialWidth:NSWidth([parent_view_ frame])
- delegate:nil
- resizeDelegate:resizeDelegate_.get()]);
- InstallAndToggleBar(bar_.get());
- }
-};
-
-TEST_F(BookmarkBarFolderControllerClosingTest, DeleteClosesFolder) {
- BookmarkModel& model(*helper_.profile()->GetBookmarkModel());
- const BookmarkNode* root = model.GetBookmarkBarNode();
- const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b ] "
- "2f3b ] 3b ");
- model_test_utils::AddNodesFromModelString(model, root, model_string);
-
- // Validate initial model.
- std::string actualModelString = model_test_utils::ModelStringFromNode(root);
- EXPECT_EQ(model_string, actualModelString);
-
- // Open the folder menu and submenu.
- BookmarkButton* target = [bar_ buttonWithTitleEqualTo:@"2f"];
- ASSERT_TRUE(target);
- [[target target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:target];
- BookmarkBarFolderController* folder = [bar_ folderController];
- EXPECT_TRUE(folder);
- BookmarkButton* subTarget = [folder buttonWithTitleEqualTo:@"2f2f"];
- ASSERT_TRUE(subTarget);
- [[subTarget target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:subTarget];
- BookmarkBarFolderController* subFolder = [folder folderController];
- EXPECT_TRUE(subFolder);
-
- // Delete the folder node and verify the window closed down by looking
- // for its controller again.
- [folder deleteBookmark:folder];
- EXPECT_FALSE([folder folderController]);
-}
-
-// TODO(jrg): draggingEntered: and draggingExited: trigger timers so
-// they are hard to test. Factor out "fire timers" into routines
-// which can be overridden to fire immediately to make behavior
-// confirmable.
-// There is a similar problem with mouseEnteredButton: and
-// mouseExitedButton:.
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h
deleted file mode 100644
index 21d0658..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-
-// Hover state machine. Encapsulates the hover state for
-// BookmarkBarFolderController.
-// A strict call order is implied with these calls. It is ONLY valid to make
-// the following state transitions:
-// From: To: Via:
-// closed opening scheduleOpen...:
-// opening closed cancelPendingOpen...: or
-// open scheduleOpen...: completes.
-// open closing scheduleClose...:
-// closing open cancelPendingClose...: or
-// closed scheduleClose...: completes.
-//
-@interface BookmarkBarFolderHoverState : NSObject {
- @private
- // Enumeration of the valid states that the |hoverButton_| member can be in.
- // Because the opening and closing of hover views can be done asyncronously
- // there are periods where the hover state is in transtion between open and
- // closed. During those times of transition the opening or closing operation
- // can be cancelled. We serialize the opening and closing of the
- // |hoverButton_| using this state information. This serialization is to
- // avoid race conditions where one hover button is being opened while another
- // is closing.
- enum HoverState {
- kHoverStateClosed = 0,
- kHoverStateOpening = 1,
- kHoverStateOpen = 2,
- kHoverStateClosing = 3
- };
-
- // Like normal menus, hovering over a folder button causes it to
- // open. This variable is set when a hover is initiated (but has
- // not necessarily fired yet).
- scoped_nsobject<BookmarkButton> hoverButton_;
-
- // We model hover state as a state machine with specific allowable
- // transitions. |hoverState_| is the state of this machine at any
- // given time.
- HoverState hoverState_;
-}
-
-// Designated initializer.
-- (id)init;
-
-// The BookmarkBarFolderHoverState decides when it is appropriate to hide
-// and show the button that the BookmarkBarFolderController drags over.
-- (NSDragOperation)draggingEnteredButton:(BookmarkButton*)button;
-
-// The BookmarkBarFolderHoverState decides the fate of the hover button
-// when the BookmarkBarFolderController's view is exited.
-- (void)draggingExited;
-
-@end
-
-// Exposing these for unit testing purposes. They are used privately in the
-// implementation as well.
-@interface BookmarkBarFolderHoverState(PrivateAPI)
-// State change APIs.
-- (void)scheduleCloseBookmarkFolderOnHoverButton;
-- (void)cancelPendingCloseBookmarkFolderOnHoverButton;
-- (void)scheduleOpenBookmarkFolderOnHoverButton:(BookmarkButton*)hoverButton;
-- (void)cancelPendingOpenBookmarkFolderOnHoverButton;
-@end
-
-// Exposing these for unit testing purposes. They are used only in tests.
-@interface BookmarkBarFolderHoverState(TestingAPI)
-// Accessors and setters for button and hover state.
-- (BookmarkButton*)hoverButton;
-- (HoverState)hoverState;
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm
deleted file mode 100644
index 2c6feee..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.mm
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-
-@interface BookmarkBarFolderHoverState(Private)
-- (void)setHoverState:(HoverState)state;
-- (void)closeBookmarkFolderOnHoverButton:(BookmarkButton*)button;
-- (void)openBookmarkFolderOnHoverButton:(BookmarkButton*)button;
-@end
-
-@implementation BookmarkBarFolderHoverState
-
-- (id)init {
- if ((self = [super init])) {
- hoverState_ = kHoverStateClosed;
- }
- return self;
-}
-
-- (NSDragOperation)draggingEnteredButton:(BookmarkButton*)button {
- if ([button isFolder]) {
- if (hoverButton_ == button) {
- // CASE A: hoverButton_ == button implies we've dragged over
- // the same folder so no need to open or close anything new.
- } else if (hoverButton_ &&
- hoverButton_ != button) {
- // CASE B: we have a hoverButton_ but it is different from the new button.
- // This implies we've dragged over a new folder, so we'll close the old
- // and open the new.
- // Note that we only schedule the open or close if we have no other tasks
- // currently pending.
-
- if (hoverState_ == kHoverStateOpen) {
- // Close the old.
- [self scheduleCloseBookmarkFolderOnHoverButton];
- } else if (hoverState_ == kHoverStateClosed) {
- // Open the new.
- [self scheduleOpenBookmarkFolderOnHoverButton:button];
- }
- } else if (!hoverButton_) {
- // CASE C: we don't have a current hoverButton_ but we have dragged onto
- // a new folder so we open the new one.
- [self scheduleOpenBookmarkFolderOnHoverButton:button];
- }
- } else if (!button) {
- if (hoverButton_) {
- // CASE D: We have a hoverButton_ but we've moved onto an area that
- // requires no hover. We close the hoverButton_ in this case. This
- // means cancelling if the open is pending (i.e. |kHoverStateOpening|)
- // or closing if we don't alrealy have once in progress.
-
- // Intiate close only if we have not already done so.
- if (hoverState_ == kHoverStateOpening) {
- // Cancel the pending open.
- [self cancelPendingOpenBookmarkFolderOnHoverButton];
- } else if (hoverState_ != kHoverStateClosing) {
- // Schedule the close.
- [self scheduleCloseBookmarkFolderOnHoverButton];
- }
- } else {
- // CASE E: We have neither a hoverButton_ nor a new button that requires
- // a hover. In this case we do nothing.
- }
- }
-
- return NSDragOperationMove;
-}
-
-- (void)draggingExited {
- if (hoverButton_) {
- if (hoverState_ == kHoverStateOpening) {
- [self cancelPendingOpenBookmarkFolderOnHoverButton];
- } else if (hoverState_ == kHoverStateClosing) {
- [self cancelPendingCloseBookmarkFolderOnHoverButton];
- }
- }
-}
-
-// Schedule close of hover button. Transition to kHoverStateClosing state.
-- (void)scheduleCloseBookmarkFolderOnHoverButton {
- DCHECK(hoverButton_);
- [self setHoverState:kHoverStateClosing];
- [self performSelector:@selector(closeBookmarkFolderOnHoverButton:)
- withObject:hoverButton_
- afterDelay:bookmarks::kDragHoverCloseDelay];
-}
-
-// Cancel pending hover close. Transition to kHoverStateOpen state.
-- (void)cancelPendingCloseBookmarkFolderOnHoverButton {
- [self setHoverState:kHoverStateOpen];
- [NSObject
- cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(closeBookmarkFolderOnHoverButton:)
- object:hoverButton_];
-}
-
-// Schedule open of hover button. Transition to kHoverStateOpening state.
-- (void)scheduleOpenBookmarkFolderOnHoverButton:(BookmarkButton*)button {
- DCHECK(button);
- hoverButton_.reset([button retain]);
- [self setHoverState:kHoverStateOpening];
- [self performSelector:@selector(openBookmarkFolderOnHoverButton:)
- withObject:hoverButton_
- afterDelay:bookmarks::kDragHoverOpenDelay];
-}
-
-// Cancel pending hover open. Transition to kHoverStateClosed state.
-- (void)cancelPendingOpenBookmarkFolderOnHoverButton {
- [self setHoverState:kHoverStateClosed];
- [NSObject
- cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(openBookmarkFolderOnHoverButton:)
- object:hoverButton_];
- hoverButton_.reset();
-}
-
-// Hover button accessor. For testing only.
-- (BookmarkButton*)hoverButton {
- return hoverButton_;
-}
-
-// Hover state accessor. For testing only.
-- (HoverState)hoverState {
- return hoverState_;
-}
-
-// This method encodes the rules of our |hoverButton_| state machine. Only
-// specific state transitions are allowable (encoded in the DCHECK).
-// Note that there is no state for simultaneously opening and closing. A
-// pending open must complete before scheduling a close, and vice versa. And
-// it is not possible to make a transition directly from open to closed, and
-// vice versa.
-- (void)setHoverState:(HoverState)state {
- DCHECK(
- (hoverState_ == kHoverStateClosed && state == kHoverStateOpening) ||
- (hoverState_ == kHoverStateOpening && state == kHoverStateClosed) ||
- (hoverState_ == kHoverStateOpening && state == kHoverStateOpen) ||
- (hoverState_ == kHoverStateOpen && state == kHoverStateClosing) ||
- (hoverState_ == kHoverStateClosing && state == kHoverStateOpen) ||
- (hoverState_ == kHoverStateClosing && state == kHoverStateClosed)
- ) << "bad transition: old = " << hoverState_ << " new = " << state;
-
- hoverState_ = state;
-}
-
-// Called after a delay to close a previously hover-opened folder.
-// Note: this method is not meant to be invoked directly, only through
-// a delayed call to |scheduleCloseBookmarkFolderOnHoverButton:|.
-- (void)closeBookmarkFolderOnHoverButton:(BookmarkButton*)button {
- [NSObject
- cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(closeBookmarkFolderOnHoverButton:)
- object:hoverButton_];
- [self setHoverState:kHoverStateClosed];
- [[button target] closeBookmarkFolder:button];
- hoverButton_.reset();
-}
-
-// Called after a delay to open a new hover folder.
-// Note: this method is not meant to be invoked directly, only through
-// a delayed call to |scheduleOpenBookmarkFolderOnHoverButton:|.
-- (void)openBookmarkFolderOnHoverButton:(BookmarkButton*)button {
- [self setHoverState:kHoverStateOpen];
- [[button target] performSelector:@selector(openBookmarkFolderFromButton:)
- withObject:button];
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state_unittest.mm
deleted file mode 100644
index bcd1293..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state_unittest.mm
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/message_loop.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_hover_state.h"
-#import "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-
-namespace {
-
-typedef CocoaTest BookmarkBarFolderHoverStateTest;
-
-// Hover state machine interface.
-// A strict call order is implied with these calls. It is ONLY valid to make
-// these specific state transitions.
-TEST(BookmarkBarFolderHoverStateTest, HoverState) {
- BrowserTestHelper helper;
- scoped_nsobject<BookmarkBarFolderHoverState> bbfhs;
- bbfhs.reset([[BookmarkBarFolderHoverState alloc] init]);
-
- // Initial state.
- EXPECT_FALSE([bbfhs hoverButton]);
- ASSERT_EQ(kHoverStateClosed, [bbfhs hoverState]);
-
- scoped_nsobject<BookmarkButton> button;
- button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0, 0, 20, 20)]);
-
- // Test transition from closed to opening.
- ASSERT_EQ(kHoverStateClosed, [bbfhs hoverState]);
- [bbfhs scheduleOpenBookmarkFolderOnHoverButton:button];
- ASSERT_EQ(kHoverStateOpening, [bbfhs hoverState]);
-
- // Test transition from opening to closed (aka cancel open).
- [bbfhs cancelPendingOpenBookmarkFolderOnHoverButton];
- ASSERT_EQ(kHoverStateClosed, [bbfhs hoverState]);
- ASSERT_EQ(nil, [bbfhs hoverButton]);
-
- // Test transition from closed to opening.
- ASSERT_EQ(kHoverStateClosed, [bbfhs hoverState]);
- [bbfhs scheduleOpenBookmarkFolderOnHoverButton:button];
- ASSERT_EQ(kHoverStateOpening, [bbfhs hoverState]);
-
- // Test transition from opening to opened.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- new MessageLoop::QuitTask,
- bookmarks::kDragHoverOpenDelay * 1000.0 * 1.5);
- MessageLoop::current()->Run();
- ASSERT_EQ(kHoverStateOpen, [bbfhs hoverState]);
- ASSERT_EQ(button, [bbfhs hoverButton]);
-
- // Test transition from opening to opened.
- [bbfhs scheduleCloseBookmarkFolderOnHoverButton];
- ASSERT_EQ(kHoverStateClosing, [bbfhs hoverState]);
-
- // Test transition from closing to open (aka cancel close).
- [bbfhs cancelPendingCloseBookmarkFolderOnHoverButton];
- ASSERT_EQ(kHoverStateOpen, [bbfhs hoverState]);
- ASSERT_EQ(button, [bbfhs hoverButton]);
-
- // Test transition from closing to closed.
- [bbfhs scheduleCloseBookmarkFolderOnHoverButton];
- ASSERT_EQ(kHoverStateClosing, [bbfhs hoverState]);
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- new MessageLoop::QuitTask,
- bookmarks::kDragHoverCloseDelay * 1000.0 * 1.5);
- MessageLoop::current()->Run();
- ASSERT_EQ(kHoverStateClosed, [bbfhs hoverState]);
- ASSERT_EQ(nil, [bbfhs hoverButton]);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h
deleted file mode 100644
index 8f60b8e..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-@protocol BookmarkButtonControllerProtocol;
-@class BookmarkBarFolderController;
-
-// Main content view for a bookmark bar folder "menu" window. This is
-// logically similar to a BookmarkBarView but is oriented vertically.
-@interface BookmarkBarFolderView : NSView {
- @private
- BOOL inDrag_; // Are we in the middle of a drag?
- BOOL dropIndicatorShown_;
- CGFloat dropIndicatorPosition_; // y position
- // The following |controller_| is weak; used for testing only. See the imple-
- // mentation comment for - (id<BookmarkButtonControllerProtocol>)controller.
- BookmarkBarFolderController* controller_;
-}
-// Return the controller that owns this view.
-- (id<BookmarkButtonControllerProtocol>)controller;
-@end
-
-@interface BookmarkBarFolderView() // TestingOrInternalAPI
-@property (assign) BOOL dropIndicatorShown;
-@property (readonly) CGFloat dropIndicatorPosition;
-- (void)setController:(id)controller;
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.mm
deleted file mode 100644
index 7cf18af..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.mm
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h"
-
-#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-
-@implementation BookmarkBarFolderView
-
-@synthesize dropIndicatorShown = dropIndicatorShown_;
-@synthesize dropIndicatorPosition = dropIndicatorPosition_;
-
-- (void)awakeFromNib {
- NSArray* types = [NSArray arrayWithObjects:
- NSStringPboardType,
- NSHTMLPboardType,
- NSURLPboardType,
- kBookmarkButtonDragType,
- kBookmarkDictionaryListPboardType,
- nil];
- [self registerForDraggedTypes:types];
-}
-
-- (void)dealloc {
- [self unregisterDraggedTypes];
- [super dealloc];
-}
-
-- (id<BookmarkButtonControllerProtocol>)controller {
- // When needed for testing, set the local data member |controller_| to
- // the test controller.
- return controller_ ? controller_ : [[self window] windowController];
-}
-
-- (void)setController:(id)controller {
- controller_ = controller;
-}
-
-- (void)drawRect:(NSRect)rect {
- // TODO(jrg): copied from bookmark_bar_view but orientation changed.
- // Code dup sucks but I'm not sure I can take 16 lines and make it
- // generic for horiz vs vertical while keeping things simple.
- // TODO(jrg): when throwing it all away and using animations, try
- // hard to make a common routine for both.
- // http://crbug.com/35966, http://crbug.com/35968
-
- // Draw the bookmark-button-dragging drop indicator if necessary.
- if (dropIndicatorShown_) {
- const CGFloat kBarHeight = 1;
- const CGFloat kBarHorizPad = 4;
- const CGFloat kBarOpacity = 0.85;
-
- NSRect uglyBlackBar =
- NSMakeRect(kBarHorizPad, dropIndicatorPosition_,
- NSWidth([self bounds]) - 2*kBarHorizPad,
- kBarHeight);
- NSColor* uglyBlackBarColor = [NSColor blackColor];
- [[uglyBlackBarColor colorWithAlphaComponent:kBarOpacity] setFill];
- [[NSBezierPath bezierPathWithRect:uglyBlackBar] fill];
- }
-}
-
-// TODO(mrossetti,jrg): Identical to -[BookmarkBarView
-// dragClipboardContainsBookmarks]. http://crbug.com/35966
-// Shim function to assist in unit testing.
-- (BOOL)dragClipboardContainsBookmarks {
- return bookmark_pasteboard_helper_mac::DragClipboardContainsBookmarks();
-}
-
-// Virtually identical to [BookmarkBarView draggingEntered:].
-// TODO(jrg): find a way to share code. Lack of multiple inheritance
-// makes things more of a pain but there should be no excuse for laziness.
-// http://crbug.com/35966
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- inDrag_ = YES;
- if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] ||
- [self dragClipboardContainsBookmarks] ||
- [[info draggingPasteboard] containsURLData]) {
- // Find the position of the drop indicator.
- BOOL showIt = [[self controller]
- shouldShowIndicatorShownForPoint:[info draggingLocation]];
- if (!showIt) {
- if (dropIndicatorShown_) {
- dropIndicatorShown_ = NO;
- [self setNeedsDisplay:YES];
- }
- } else {
- CGFloat y =
- [[self controller]
- indicatorPosForDragToPoint:[info draggingLocation]];
-
- // Need an update if the indicator wasn't previously shown or if it has
- // moved.
- if (!dropIndicatorShown_ || dropIndicatorPosition_ != y) {
- dropIndicatorShown_ = YES;
- dropIndicatorPosition_ = y;
- [self setNeedsDisplay:YES];
- }
- }
-
- [[self controller] draggingEntered:info]; // allow hover-open to work
- return [info draggingSource] ? NSDragOperationMove : NSDragOperationCopy;
- }
- return NSDragOperationNone;
-}
-
-- (void)draggingExited:(id<NSDraggingInfo>)info {
- [[self controller] draggingExited:info];
-
- // Regardless of the type of dragging which ended, we need to get rid of the
- // drop indicator if one was shown.
- if (dropIndicatorShown_) {
- dropIndicatorShown_ = NO;
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)draggingEnded:(id<NSDraggingInfo>)info {
- // Awkwardness since views open and close out from under us.
- if (inDrag_) {
- inDrag_ = NO;
- }
-
- [self draggingExited:info];
-}
-
-- (BOOL)wantsPeriodicDraggingUpdates {
- // TODO(jrg): This should probably return |YES| and the controller should
- // slide the existing bookmark buttons interactively to the side to make
- // room for the about-to-be-dropped bookmark.
- // http://crbug.com/35968
- return NO;
-}
-
-- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
- // For now it's the same as draggingEntered:.
- // TODO(jrg): once we return YES for wantsPeriodicDraggingUpdates,
- // this should ping the [self controller] to perform animations.
- // http://crbug.com/35968
- return [self draggingEntered:info];
-}
-
-- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
- return YES;
-}
-
-// This code is practically identical to the same function in BookmarkBarView
-// with the only difference being how the controller is retrieved.
-// TODO(mrossetti,jrg): http://crbug.com/35966
-// Implement NSDraggingDestination protocol method
-// performDragOperation: for URLs.
-- (BOOL)performDragOperationForURL:(id<NSDraggingInfo>)info {
- NSPasteboard* pboard = [info draggingPasteboard];
- DCHECK([pboard containsURLData]);
-
- NSArray* urls = nil;
- NSArray* titles = nil;
- [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
-
- return [[self controller] addURLs:urls
- withTitles:titles
- at:[info draggingLocation]];
-}
-
-// This code is practically identical to the same function in BookmarkBarView
-// with the only difference being how the controller is retrieved.
-// http://crbug.com/35966
-// Implement NSDraggingDestination protocol method
-// performDragOperation: for bookmark buttons.
-- (BOOL)performDragOperationForBookmarkButton:(id<NSDraggingInfo>)info {
- BOOL doDrag = NO;
- NSData* data = [[info draggingPasteboard]
- dataForType:kBookmarkButtonDragType];
- // [info draggingSource] is nil if not the same application.
- if (data && [info draggingSource]) {
- BookmarkButton* button = nil;
- [data getBytes:&button length:sizeof(button)];
- BOOL copy = !([info draggingSourceOperationMask] & NSDragOperationMove);
- doDrag = [[self controller] dragButton:button
- to:[info draggingLocation]
- copy:copy];
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBarFolder_DragEnd"));
- }
- return doDrag;
-}
-
-- (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
- if ([[self controller] dragBookmarkData:info])
- return YES;
- NSPasteboard* pboard = [info draggingPasteboard];
- if ([pboard dataForType:kBookmarkButtonDragType] &&
- [self performDragOperationForBookmarkButton:info])
- return YES;
- if ([pboard containsURLData] && [self performDragOperationForURL:info])
- return YES;
- return NO;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
deleted file mode 100644
index 9abe55a..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view_unittest.mm
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/cocoa/url_drop_target.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-
-namespace {
- const CGFloat kFakeIndicatorPos = 7.0;
-};
-
-// Fake DraggingInfo, fake BookmarkBarController, fake NSPasteboard...
-@interface FakeDraggingInfo : NSObject {
- @public
- BOOL dragButtonToPong_;
- BOOL dragURLsPong_;
- BOOL dragBookmarkDataPong_;
- BOOL dropIndicatorShown_;
- BOOL draggingEnteredCalled_;
- // Only mock one type of drag data at a time.
- NSString* dragDataType_;
-}
-@property (readwrite) BOOL dropIndicatorShown;
-@property (readwrite) BOOL draggingEnteredCalled;
-@property (copy) NSString* dragDataType;
-@end
-
-@implementation FakeDraggingInfo
-
-@synthesize dropIndicatorShown = dropIndicatorShown_;
-@synthesize draggingEnteredCalled = draggingEnteredCalled_;
-@synthesize dragDataType = dragDataType_;
-
-- (id)init {
- if ((self = [super init])) {
- dropIndicatorShown_ = YES;
- }
- return self;
-}
-
-- (void)dealloc {
- [dragDataType_ release];
- [super dealloc];
-}
-
-- (void)reset {
- [dragDataType_ release];
- dragDataType_ = nil;
- dragButtonToPong_ = NO;
- dragURLsPong_ = NO;
- dragBookmarkDataPong_ = NO;
- dropIndicatorShown_ = YES;
- draggingEnteredCalled_ = NO;
-}
-
-// NSDragInfo mocking functions.
-
-- (id)draggingPasteboard {
- return self;
-}
-
-// So we can look local.
-- (id)draggingSource {
- return self;
-}
-
-- (NSDragOperation)draggingSourceOperationMask {
- return NSDragOperationCopy | NSDragOperationMove;
-}
-
-- (NSPoint)draggingLocation {
- return NSMakePoint(10, 10);
-}
-
-// NSPasteboard mocking functions.
-
-- (BOOL)containsURLData {
- NSArray* urlTypes = [URLDropTargetHandler handledDragTypes];
- if (dragDataType_)
- return [urlTypes containsObject:dragDataType_];
- return NO;
-}
-
-- (NSData*)dataForType:(NSString*)type {
- if (dragDataType_ && [dragDataType_ isEqualToString:type])
- return [NSData data]; // Return something, anything.
- return nil;
-}
-
-// Fake a controller for callback ponging
-
-- (BOOL)dragButton:(BookmarkButton*)button to:(NSPoint)point copy:(BOOL)copy {
- dragButtonToPong_ = YES;
- return YES;
-}
-
-- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point {
- dragURLsPong_ = YES;
- return YES;
-}
-
-- (void)getURLs:(NSArray**)outUrls
- andTitles:(NSArray**)outTitles
- convertingFilenames:(BOOL)convertFilenames {
-}
-
-- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info {
- dragBookmarkDataPong_ = YES;
- return NO;
-}
-
-// Confirm the pongs.
-
-- (BOOL)dragButtonToPong {
- return dragButtonToPong_;
-}
-
-- (BOOL)dragURLsPong {
- return dragURLsPong_;
-}
-
-- (BOOL)dragBookmarkDataPong {
- return dragBookmarkDataPong_;
-}
-
-- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point {
- return kFakeIndicatorPos;
-}
-
-- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point {
- return dropIndicatorShown_;
-}
-
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- draggingEnteredCalled_ = YES;
- return NSDragOperationNone;
-}
-
-@end
-
-namespace {
-
-class BookmarkBarFolderViewTest : public CocoaTest {
- public:
- virtual void SetUp() {
- CocoaTest::SetUp();
- view_.reset([[BookmarkBarFolderView alloc] init]);
- }
-
- scoped_nsobject<BookmarkBarFolderView> view_;
-};
-
-TEST_F(BookmarkBarFolderViewTest, BookmarkButtonDragAndDrop) {
- [view_ awakeFromNib];
- scoped_nsobject<FakeDraggingInfo> info([[FakeDraggingInfo alloc] init]);
- [view_ setController:info.get()];
- [info reset];
-
- [info setDragDataType:kBookmarkButtonDragType];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([view_ performDragOperation:(id)info.get()]);
- EXPECT_TRUE([info dragButtonToPong]);
- EXPECT_FALSE([info dragURLsPong]);
- EXPECT_TRUE([info dragBookmarkDataPong]);
-}
-
-TEST_F(BookmarkBarFolderViewTest, URLDragAndDrop) {
- [view_ awakeFromNib];
- scoped_nsobject<FakeDraggingInfo> info([[FakeDraggingInfo alloc] init]);
- [view_ setController:info.get()];
- [info reset];
-
- NSArray* dragTypes = [URLDropTargetHandler handledDragTypes];
- for (NSString* type in dragTypes) {
- [info setDragDataType:type];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([view_ performDragOperation:(id)info.get()]);
- EXPECT_FALSE([info dragButtonToPong]);
- EXPECT_TRUE([info dragURLsPong]);
- EXPECT_TRUE([info dragBookmarkDataPong]);
- [info reset];
- }
-}
-
-TEST_F(BookmarkBarFolderViewTest, BookmarkButtonDropIndicator) {
- [view_ awakeFromNib];
- scoped_nsobject<FakeDraggingInfo> info([[FakeDraggingInfo alloc] init]);
- [view_ setController:info.get()];
- [info reset];
-
- [info setDragDataType:kBookmarkButtonDragType];
- EXPECT_FALSE([info draggingEnteredCalled]);
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([info draggingEnteredCalled]); // Ensure controller pinged.
- EXPECT_TRUE([view_ dropIndicatorShown]);
- EXPECT_EQ([view_ dropIndicatorPosition], kFakeIndicatorPos);
-
- [info setDropIndicatorShown:NO];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_FALSE([view_ dropIndicatorShown]);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h
deleted file mode 100644
index 4b85277..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_WINDOW_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_WINDOW_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-#import "base/cocoa_protocols_mac.h"
-#include "base/scoped_nsobject.h"
-
-
-// Window for a bookmark folder "menu". This menu pops up when you
-// click on a bookmark button that represents a folder of bookmarks.
-// This window is borderless.
-@interface BookmarkBarFolderWindow : NSWindow
-@end
-
-// Content view for the above window. "Stock" other than the drawing
-// of rounded corners. Only used in the nib.
-@interface BookmarkBarFolderWindowContentView : NSView {
- // Arrows to show ability to scroll up and down as needed.
- scoped_nsobject<NSImage> arrowUpImage_;
- scoped_nsobject<NSImage> arrowDownImage_;
-}
-@end
-
-// Scroll view that contains the main view (where the buttons go).
-@interface BookmarkBarFolderWindowScrollView : NSScrollView
-@end
-
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_WINDOW_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.mm
deleted file mode 100644
index 5e51a81..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.mm
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h"
-
-#import "base/logging.h"
-#include "base/nsimage_cache_mac.h"
-#import "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/image_utils.h"
-#import "third_party/GTM/AppKit/GTMNSColor+Luminance.h"
-#import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h"
-
-
-@implementation BookmarkBarFolderWindow
-
-- (id)initWithContentRect:(NSRect)contentRect
- styleMask:(NSUInteger)windowStyle
- backing:(NSBackingStoreType)bufferingType
- defer:(BOOL)deferCreation {
- if ((self = [super initWithContentRect:contentRect
- styleMask:NSBorderlessWindowMask // override
- backing:bufferingType
- defer:deferCreation])) {
- [self setBackgroundColor:[NSColor clearColor]];
- [self setOpaque:NO];
- }
- return self;
-}
-
-@end
-
-
-namespace {
-// Corner radius for our bookmark bar folder window.
-// Copied from bubble_view.mm.
-const CGFloat kViewCornerRadius = 4.0;
-}
-
-@implementation BookmarkBarFolderWindowContentView
-
-- (void)awakeFromNib {
- arrowUpImage_.reset([nsimage_cache::ImageNamed(@"menu_overflow_up.pdf")
- retain]);
- arrowDownImage_.reset([nsimage_cache::ImageNamed(@"menu_overflow_down.pdf")
- retain]);
-}
-
-// Draw the arrows at the top and bottom of the folder window as a
-// visual indication that scrolling is possible. We always draw the
-// scrolling arrows; when not relevant (e.g. when not scrollable), the
-// scroll view overlaps the window and the arrows aren't visible.
-- (void)drawScrollArrows:(NSRect)rect {
- NSRect visibleRect = [self bounds];
-
- // On top
- NSRect imageRect = NSZeroRect;
- imageRect.size = [arrowUpImage_ size];
- NSRect drawRect = NSOffsetRect(
- imageRect,
- (NSWidth(visibleRect) - NSWidth(imageRect)) / 2,
- NSHeight(visibleRect) - NSHeight(imageRect));
- [arrowUpImage_ drawInRect:drawRect
- fromRect:imageRect
- operation:NSCompositeSourceOver
- fraction:1.0
- neverFlipped:YES];
-
- // On bottom
- imageRect = NSZeroRect;
- imageRect.size = [arrowDownImage_ size];
- drawRect = NSOffsetRect(imageRect,
- (NSWidth(visibleRect) - NSWidth(imageRect)) / 2,
- 0);
- [arrowDownImage_ drawInRect:drawRect
- fromRect:imageRect
- operation:NSCompositeSourceOver
- fraction:1.0
- neverFlipped:YES];
-}
-
-- (void)drawRect:(NSRect)rect {
- NSRect bounds = [self bounds];
- // Like NSMenus, only the bottom corners are rounded.
- NSBezierPath* bezier =
- [NSBezierPath gtm_bezierPathWithRoundRect:bounds
- topLeftCornerRadius:0
- topRightCornerRadius:0
- bottomLeftCornerRadius:kViewCornerRadius
- bottomRightCornerRadius:kViewCornerRadius];
- [bezier closePath];
-
- // TODO(jrg): share code with info_bubble_view.mm? Or bubble_view.mm?
- NSColor* base_color = [NSColor colorWithCalibratedWhite:0.5 alpha:1.0];
- NSColor* startColor =
- [base_color gtm_colorAdjustedFor:GTMColorationLightHighlight
- faded:YES];
- NSColor* midColor =
- [base_color gtm_colorAdjustedFor:GTMColorationLightMidtone
- faded:YES];
- NSColor* endColor =
- [base_color gtm_colorAdjustedFor:GTMColorationLightShadow
- faded:YES];
- NSColor* glowColor =
- [base_color gtm_colorAdjustedFor:GTMColorationLightPenumbra
- faded:YES];
-
- scoped_nsobject<NSGradient> gradient(
- [[NSGradient alloc] initWithColorsAndLocations:startColor, 0.0,
- midColor, 0.25,
- endColor, 0.5,
- glowColor, 0.75,
- nil]);
- [gradient drawInBezierPath:bezier angle:0.0];
-
- [self drawScrollArrows:rect];
-}
-
-@end
-
-
-@implementation BookmarkBarFolderWindowScrollView
-
-// We want "draw background" of the NSScrollView in the xib to be NOT
-// checked. That allows us to round the bottom corners of the folder
-// window. However that also allows some scrollWheel: events to leak
-// into the NSWindow behind it (even in a different application).
-// Better to plug the scroll leak than to round corners for M5.
-- (void)scrollWheel:(NSEvent *)theEvent {
- DCHECK([[[self window] windowController]
- respondsToSelector:@selector(scrollWheel:)]);
- [[[self window] windowController] scrollWheel:theEvent];
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm
deleted file mode 100644
index d291390..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window_unittest.mm
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/scoped_ptr.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h"
-#include "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-class BookmarkBarFolderWindowTest : public CocoaTest {
-};
-
-TEST_F(BookmarkBarFolderWindowTest, Borderless) {
- scoped_nsobject<BookmarkBarFolderWindow> window_;
- window_.reset([[BookmarkBarFolderWindow alloc]
- initWithContentRect:NSMakeRect(0,0,20,20)
- styleMask:0
- backing:NSBackingStoreBuffered
- defer:NO]);
- EXPECT_EQ(NSBorderlessWindowMask, [window_ styleMask]);
-}
-
-
-class BookmarkBarFolderWindowContentViewTest : public CocoaTest {
- public:
- BookmarkBarFolderWindowContentViewTest() {
- view_.reset([[BookmarkBarFolderWindowContentView alloc]
- initWithFrame:NSMakeRect(0, 0, 100, 100)]);
- [[test_window() contentView] addSubview:view_.get()];
- }
- scoped_nsobject<BookmarkBarFolderWindowContentView> view_;
- scoped_nsobject<BookmarkBarFolderWindowScrollView> scroll_view_;
-};
-
-TEST_VIEW(BookmarkBarFolderWindowContentViewTest, view_);
-
-
-class BookmarkBarFolderWindowScrollViewTest : public CocoaTest {
- public:
- BookmarkBarFolderWindowScrollViewTest() {
- scroll_view_.reset([[BookmarkBarFolderWindowScrollView alloc]
- initWithFrame:NSMakeRect(0, 0, 100, 100)]);
- [[test_window() contentView] addSubview:scroll_view_.get()];
- }
- scoped_nsobject<BookmarkBarFolderWindowScrollView> scroll_view_;
-};
-
-TEST_VIEW(BookmarkBarFolderWindowScrollViewTest, scroll_view_);
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_state.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_state.h
deleted file mode 100644
index 4f98b5c..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_state.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BAR_STATE_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_STATE_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-namespace bookmarks {
-
-// States for the bookmark bar.
-enum VisualState {
- kInvalidState = 0,
- kHiddenState = 1,
- kShowingState = 2,
- kDetachedState = 3,
-};
-
-} // namespace bookmarks
-
-// The interface for controllers (etc.) which can give information about the
-// bookmark bar's state.
-@protocol BookmarkBarState
-
-// Returns YES if the bookmark bar is currently visible (as a normal toolbar or
-// as a detached bar on the NTP), NO otherwise.
-- (BOOL)isVisible;
-
-// Returns YES if an animation is currently running, NO otherwise.
-- (BOOL)isAnimationRunning;
-
-// Returns YES if the bookmark bar is in the given state and not in an
-// animation, NO otherwise.
-- (BOOL)isInState:(bookmarks::VisualState)state;
-
-// Returns YES if the bookmark bar is animating from the given state (to any
-// other state), NO otherwise.
-- (BOOL)isAnimatingToState:(bookmarks::VisualState)state;
-
-// Returns YES if the bookmark bar is animating to the given state (from any
-// other state), NO otherwise.
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)state;
-
-// Returns YES if the bookmark bar is animating from the first given state to
-// the second given state, NO otherwise.
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)fromState
- toState:(bookmarks::VisualState)toState;
-
-// Returns YES if the bookmark bar is animating between the two given states (in
-// either direction), NO otherwise.
-- (BOOL)isAnimatingBetweenState:(bookmarks::VisualState)fromState
- andState:(bookmarks::VisualState)toState;
-
-// Returns how morphed into the detached bubble the bookmark bar should be (1 =
-// completely detached, 0 = normal).
-- (CGFloat)detachedMorphProgress;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_STATE_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h
deleted file mode 100644
index cdc6e9c..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2010 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.
-
-// The BookmarkBarToolbarView is responsible for drawing the background of the
-// BookmarkBar's toolbar in either of its two display modes - permanently
-// attached (slimline with a stroke at the bottom edge) or New Tab Page style
-// (padded with a round rect border and the New Tab Page theme behind).
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_TOOLBAR_VIEW_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_TOOLBAR_VIEW_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#import "chrome/browser/cocoa/animatable_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_state.h"
-
-@class BookmarkBarView;
-class TabContents;
-class ThemeProvider;
-
-// An interface to allow mocking of a BookmarkBarController by the
-// BookmarkBarToolbarView.
-@protocol BookmarkBarToolbarViewController <BookmarkBarState>
-// Displaying the bookmark toolbar background in bubble (floating) mode requires
-// the size of the currently selected tab to properly calculate where the
-// background image is joined.
-- (int)currentTabContentsHeight;
-
-// Current theme provider, passed to the cross platform NtpBackgroundUtil class.
-- (ThemeProvider*)themeProvider;
-
-@end
-
-@interface BookmarkBarToolbarView : AnimatableView {
- @private
- // The controller which tells us how we should be drawing (as normal or as a
- // floating bar).
- IBOutlet id<BookmarkBarToolbarViewController> controller_;
-}
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_TOOLBAR_VIEW_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.mm
deleted file mode 100644
index 6abf516..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.mm
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
-
-#include "app/theme_provider.h"
-#include "gfx/rect.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/themed_window.h"
-#include "chrome/browser/ntp_background_util.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
-#include "gfx/canvas_skia_paint.h"
-
-const CGFloat kBorderRadius = 3.0;
-
-@interface BookmarkBarToolbarView (Private)
-- (void)drawRectAsBubble:(NSRect)rect;
-@end
-
-@implementation BookmarkBarToolbarView
-
-- (BOOL)isOpaque {
- return [controller_ isInState:bookmarks::kDetachedState];
-}
-
-- (void)drawRect:(NSRect)rect {
- if ([controller_ isInState:bookmarks::kDetachedState] ||
- [controller_ isAnimatingToState:bookmarks::kDetachedState] ||
- [controller_ isAnimatingFromState:bookmarks::kDetachedState]) {
- [self drawRectAsBubble:rect];
- } else {
- NSPoint phase = [[self window] themePatternPhase];
- [[NSGraphicsContext currentContext] setPatternPhase:phase];
- [self drawBackground];
- }
-}
-
-- (void)drawRectAsBubble:(NSRect)rect {
- // The state of our morph; 1 is total bubble, 0 is the regular bar. We use it
- // to morph the bubble to a regular bar (shape and colour).
- CGFloat morph = [controller_ detachedMorphProgress];
-
- NSRect bounds = [self bounds];
-
- ThemeProvider* themeProvider = [controller_ themeProvider];
- if (!themeProvider)
- return;
-
- NSGraphicsContext* context = [NSGraphicsContext currentContext];
- [context saveGraphicsState];
-
- // Draw the background.
- {
- // CanvasSkiaPaint draws to the NSGraphicsContext during its destructor, so
- // explicitly scope this.
- //
- // Paint the entire bookmark bar, even if the damage rect is much smaller
- // because PaintBackgroundDetachedMode() assumes that area's origin is
- // (0, 0) and that its size is the size of the bookmark bar.
- //
- // In practice, this sounds worse than it is because redraw time is still
- // minimal compared to the pause between frames of animations. We were
- // already repainting the rest of the bookmark bar below without setting a
- // clip area, anyway. Also, the only time we weren't asked to redraw the
- // whole bookmark bar is when the find bar is drawn over it.
- gfx::CanvasSkiaPaint canvas(bounds, true);
- gfx::Rect area(0, 0, NSWidth(bounds), NSHeight(bounds));
-
- NtpBackgroundUtil::PaintBackgroundDetachedMode(themeProvider, &canvas,
- area, [controller_ currentTabContentsHeight]);
- }
-
- // Draw our bookmark bar border on top of the background.
- NSRect frameRect =
- NSMakeRect(
- morph * bookmarks::kNTPBookmarkBarPadding,
- morph * bookmarks::kNTPBookmarkBarPadding,
- NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding,
- NSHeight(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding);
- // Now draw a bezier path with rounded rectangles around the area.
- frameRect = NSInsetRect(frameRect, morph * 0.5, morph * 0.5);
- NSBezierPath* border =
- [NSBezierPath bezierPathWithRoundedRect:frameRect
- xRadius:(morph * kBorderRadius)
- yRadius:(morph * kBorderRadius)];
-
- // Draw the rounded rectangle.
- NSColor* toolbarColor =
- themeProvider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR, true);
- CGFloat alpha = morph * [toolbarColor alphaComponent];
- [[toolbarColor colorWithAlphaComponent:alpha] set]; // Set with opacity.
- [border fill];
-
- // Fade in/out the background.
- [context saveGraphicsState];
- [border setClip];
- CGContextRef cgContext = (CGContextRef)[context graphicsPort];
- CGContextBeginTransparencyLayer(cgContext, NULL);
- CGContextSetAlpha(cgContext, 1 - morph);
- [context setPatternPhase:[[self window] themePatternPhase]];
- [self drawBackground];
- CGContextEndTransparencyLayer(cgContext);
- [context restoreGraphicsState];
-
- // Draw the border of the rounded rectangle.
- NSColor* borderColor = themeProvider->GetNSColor(
- BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE, true);
- alpha = morph * [borderColor alphaComponent];
- [[borderColor colorWithAlphaComponent:alpha] set]; // Set with opacity.
- [border stroke];
-
- // Fade in/out the divider.
- // TODO(viettrungluu): It's not obvious that this divider lines up exactly
- // with |BackgroundGradientView|'s (in fact, it probably doesn't).
- NSColor* strokeColor = [self strokeColor];
- alpha = (1 - morph) * [strokeColor alphaComponent];
- [[strokeColor colorWithAlphaComponent:alpha] set];
- NSBezierPath* divider = [NSBezierPath bezierPath];
- NSPoint dividerStart =
- NSMakePoint(morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5,
- morph * bookmarks::kNTPBookmarkBarPadding + morph * 0.5);
- CGFloat dividerWidth =
- NSWidth(bounds) - 2 * morph * bookmarks::kNTPBookmarkBarPadding - 2 * 0.5;
- [divider moveToPoint:dividerStart];
- [divider relativeLineToPoint:NSMakePoint(dividerWidth, 0)];
- [divider stroke];
-
- // Restore the graphics context.
- [context restoreGraphicsState];
-}
-
-@end // @implementation BookmarkBarToolbarView
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm
deleted file mode 100644
index aecdf84..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view_unittest.mm
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "app/theme_provider.h"
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
-#include "grit/theme_resources.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-using ::testing::_;
-using ::testing::DoAll;
-using ::testing::Return;
-using ::testing::SetArgumentPointee;
-
-// When testing the floating drawing, we need to have a source of theme data.
-class MockThemeProvider : public ThemeProvider {
- public:
- // Cross platform methods
- MOCK_METHOD1(Init, void(Profile*));
- MOCK_CONST_METHOD1(GetBitmapNamed, SkBitmap*(int));
- MOCK_CONST_METHOD1(GetColor, SkColor(int));
- MOCK_CONST_METHOD2(GetDisplayProperty, bool(int, int*));
- MOCK_CONST_METHOD0(ShouldUseNativeFrame, bool());
- MOCK_CONST_METHOD1(HasCustomImage, bool(int));
- MOCK_CONST_METHOD1(GetRawData, RefCountedMemory*(int));
-
- // OSX stuff
- MOCK_CONST_METHOD2(GetNSImageNamed, NSImage*(int, bool));
- MOCK_CONST_METHOD2(GetNSImageColorNamed, NSColor*(int, bool));
- MOCK_CONST_METHOD2(GetNSColor, NSColor*(int, bool));
- MOCK_CONST_METHOD2(GetNSColorTint, NSColor*(int, bool));
- MOCK_CONST_METHOD1(GetNSGradient, NSGradient*(int));
-};
-
-// Allows us to inject our fake controller below.
-@interface BookmarkBarToolbarView (TestingAPI)
--(void)setController:(id<BookmarkBarToolbarViewController>)controller;
-@end
-
-@implementation BookmarkBarToolbarView (TestingAPI)
--(void)setController:(id<BookmarkBarToolbarViewController>)controller {
- controller_ = controller;
-}
-@end
-
-// Allows us to control which way the view is rendered.
-@interface DrawDetachedBarFakeController :
- NSObject<BookmarkBarState, BookmarkBarToolbarViewController> {
- @private
- int currentTabContentsHeight_;
- ThemeProvider* themeProvider_;
- bookmarks::VisualState visualState_;
-}
-@property (nonatomic, assign) int currentTabContentsHeight;
-@property (nonatomic, assign) ThemeProvider* themeProvider;
-@property (nonatomic, assign) bookmarks::VisualState visualState;
-
-// |BookmarkBarState| protocol:
-- (BOOL)isVisible;
-- (BOOL)isAnimationRunning;
-- (BOOL)isInState:(bookmarks::VisualState)state;
-- (BOOL)isAnimatingToState:(bookmarks::VisualState)state;
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)state;
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)fromState
- toState:(bookmarks::VisualState)toState;
-- (BOOL)isAnimatingBetweenState:(bookmarks::VisualState)fromState
- andState:(bookmarks::VisualState)toState;
-- (CGFloat)detachedMorphProgress;
-@end
-
-@implementation DrawDetachedBarFakeController
-@synthesize currentTabContentsHeight = currentTabContentsHeight_;
-@synthesize themeProvider = themeProvider_;
-@synthesize visualState = visualState_;
-
-- (id)init {
- if ((self = [super init])) {
- [self setVisualState:bookmarks::kHiddenState];
- }
- return self;
-}
-
-- (BOOL)isVisible { return YES; }
-- (BOOL)isAnimationRunning { return NO; }
-- (BOOL)isInState:(bookmarks::VisualState)state
- { return ([self visualState] == state) ? YES : NO; }
-- (BOOL)isAnimatingToState:(bookmarks::VisualState)state { return NO; }
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)state { return NO; }
-- (BOOL)isAnimatingFromState:(bookmarks::VisualState)fromState
- toState:(bookmarks::VisualState)toState { return NO; }
-- (BOOL)isAnimatingBetweenState:(bookmarks::VisualState)fromState
- andState:(bookmarks::VisualState)toState { return NO; }
-- (CGFloat)detachedMorphProgress { return 1; }
-@end
-
-class BookmarkBarToolbarViewTest : public CocoaTest {
- public:
- BookmarkBarToolbarViewTest() {
- controller_.reset([[DrawDetachedBarFakeController alloc] init]);
- NSRect frame = NSMakeRect(0, 0, 400, 40);
- scoped_nsobject<BookmarkBarToolbarView> view(
- [[BookmarkBarToolbarView alloc] initWithFrame:frame]);
- view_ = view.get();
- [[test_window() contentView] addSubview:view_];
- [view_ setController:controller_.get()];
- }
-
- scoped_nsobject<DrawDetachedBarFakeController> controller_;
- BookmarkBarToolbarView* view_;
-};
-
-TEST_VIEW(BookmarkBarToolbarViewTest, view_)
-
-// Test drawing (part 1), mostly to ensure nothing leaks or crashes.
-TEST_F(BookmarkBarToolbarViewTest, DisplayAsNormalBar) {
- [controller_.get() setVisualState:bookmarks::kShowingState];
- [view_ display];
-}
-
-// Test drawing (part 2), mostly to ensure nothing leaks or crashes.
-TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithNoImage) {
- [controller_.get() setVisualState:bookmarks::kDetachedState];
-
- // Tests where we don't have a background image, only a color.
- MockThemeProvider provider;
- EXPECT_CALL(provider, GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND))
- .WillRepeatedly(Return(SK_ColorWHITE));
- EXPECT_CALL(provider, HasCustomImage(IDR_THEME_NTP_BACKGROUND))
- .WillRepeatedly(Return(false));
- [controller_.get() setThemeProvider:&provider];
-
- [view_ display];
-}
-
-// Actions used in DisplayAsDetachedBarWithBgImage.
-ACTION(SetBackgroundTiling) {
- *arg1 = BrowserThemeProvider::NO_REPEAT;
- return true;
-}
-
-ACTION(SetAlignLeft) {
- *arg1 = BrowserThemeProvider::ALIGN_LEFT;
- return true;
-}
-
-// Test drawing (part 3), mostly to ensure nothing leaks or crashes.
-TEST_F(BookmarkBarToolbarViewTest, DisplayAsDetachedBarWithBgImage) {
- [controller_.get() setVisualState:bookmarks::kDetachedState];
-
- // Tests where we have a background image, with positioning information.
- MockThemeProvider provider;
-
- // Advertise having an image.
- EXPECT_CALL(provider, GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND))
- .WillRepeatedly(Return(SK_ColorRED));
- EXPECT_CALL(provider, HasCustomImage(IDR_THEME_NTP_BACKGROUND))
- .WillRepeatedly(Return(true));
-
- // Return the correct tiling/alignment information.
- EXPECT_CALL(provider,
- GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_TILING, _))
- .WillRepeatedly(SetBackgroundTiling());
- EXPECT_CALL(provider,
- GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, _))
- .WillRepeatedly(SetAlignLeft());
-
- // Create a dummy bitmap full of not-red to blit with.
- SkBitmap fake_bg;
- fake_bg.setConfig(SkBitmap::kARGB_8888_Config, 800, 800);
- fake_bg.allocPixels();
- fake_bg.eraseColor(SK_ColorGREEN);
- EXPECT_CALL(provider, GetBitmapNamed(IDR_THEME_NTP_BACKGROUND))
- .WillRepeatedly(Return(&fake_bg));
-
- [controller_.get() setThemeProvider:&provider];
- [controller_.get() setCurrentTabContentsHeight:200];
-
- [view_ display];
-}
-
-// TODO(viettrungluu): write more unit tests, especially after my refactoring.
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h
deleted file mode 100644
index edd60d2..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BAR_UNITTEST_HELPER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_UNITTEST_HELPER_H_
-#pragma once
-
-#import <Foundation/Foundation.h>
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-
-@interface BookmarkBarController (BookmarkBarUnitTestHelper)
-
-// Return the bookmark button from this bar controller with the given
-// |title|, otherwise nil. This does not recurse into folders.
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title;
-
-@end
-
-
-@interface BookmarkBarFolderController (BookmarkBarUnitTestHelper)
-
-// Return the bookmark button from this folder controller with the given
-// |title|, otherwise nil. This does not recurse into subfolders.
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title;
-
-@end
-
-
-@interface BookmarkButton (BookmarkBarUnitTestHelper)
-
-// Return the center of the button in the base coordinate system of the
-// containing window. Useful for simulating mouse clicks or drags.
-- (NSPoint)center;
-
-// Return the top of the button in the base coordinate system of the
-// containing window.
-- (NSPoint)top;
-
-// Return the bottom of the button in the base coordinate system of the
-// containing window.
-- (NSPoint)bottom;
-
-// Return the center-left point of the button in the base coordinate system
-// of the containing window.
-- (NSPoint)left;
-
-// Return the center-right point of the button in the base coordinate system
-// of the containing window.
-- (NSPoint)right;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_UNITTEST_HELPER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.mm
deleted file mode 100644
index c8eefdb..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.mm
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_unittest_helper.h"
-
-@interface NSArray (BookmarkBarUnitTestHelper)
-
-// A helper function for scanning an array of buttons looking for the
-// button with the given |title|.
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title;
-
-@end
-
-
-@implementation NSArray (BookmarkBarUnitTestHelper)
-
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title {
- for (BookmarkButton* button in self) {
- if ([[button title] isEqualToString:title])
- return button;
- }
- return nil;
-}
-
-@end
-
-@implementation BookmarkBarController (BookmarkBarUnitTestHelper)
-
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title {
- return [[self buttons] buttonWithTitleEqualTo:title];
-}
-
-@end
-
-@implementation BookmarkBarFolderController(BookmarkBarUnitTestHelper)
-
-- (BookmarkButton*)buttonWithTitleEqualTo:(NSString*)title {
- return [[self buttons] buttonWithTitleEqualTo:title];
-}
-
-@end
-
-@implementation BookmarkButton(BookmarkBarUnitTestHelper)
-
-- (NSPoint)center {
- NSRect frame = [self frame];
- NSPoint center = NSMakePoint(NSMidX(frame), NSMidY(frame));
- center = [[self superview] convertPoint:center toView:nil];
- return center;
-}
-
-- (NSPoint)top {
- NSRect frame = [self frame];
- NSPoint top = NSMakePoint(NSMidX(frame), NSMaxY(frame));
- top = [[self superview] convertPoint:top toView:nil];
- return top;
-}
-
-- (NSPoint)bottom {
- NSRect frame = [self frame];
- NSPoint bottom = NSMakePoint(NSMidX(frame), NSMinY(frame));
- bottom = [[self superview] convertPoint:bottom toView:nil];
- return bottom;
-}
-
-- (NSPoint)left {
- NSRect frame = [self frame];
- NSPoint left = NSMakePoint(NSMinX(frame), NSMidY(frame));
- left = [[self superview] convertPoint:left toView:nil];
- return left;
-}
-
-- (NSPoint)right {
- NSRect frame = [self frame];
- NSPoint right = NSMakePoint(NSMaxX(frame), NSMidY(frame));
- right = [[self superview] convertPoint:right toView:nil];
- return right;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_view.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_view.h
deleted file mode 100644
index a409171..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_view.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2010 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.
-//
-// A simple custom NSView for the bookmark bar used to prevent clicking and
-// dragging from moving the browser window.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_VIEW_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_VIEW_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#import "chrome/browser/cocoa/background_gradient_view.h"
-
-@class BookmarkBarController;
-
-@interface BookmarkBarView : BackgroundGradientView {
- @private
- BOOL dropIndicatorShown_;
- CGFloat dropIndicatorPosition_; // x position
-
- IBOutlet BookmarkBarController* controller_;
- IBOutlet NSTextField* noItemTextfield_;
- IBOutlet NSButton* importBookmarksButton_;
- NSView* noItemContainer_;
-}
-- (NSTextField*)noItemTextfield;
-- (NSButton*)importBookmarksButton;
-- (BookmarkBarController*)controller;
-
-@property (nonatomic, assign) IBOutlet NSView* noItemContainer;
-@end
-
-@interface BookmarkBarView() // TestingOrInternalAPI
-@property (nonatomic, readonly) BOOL dropIndicatorShown;
-@property (nonatomic, readonly) CGFloat dropIndicatorPosition;
-- (void)setController:(id)controller;
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BAR_VIEW_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_view.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_view.mm
deleted file mode 100644
index 667cff1..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_view.mm
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_view.h"
-
-#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#import "chrome/browser/cocoa/themed_window.h"
-#import "chrome/browser/cocoa/view_id_util.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#import "chrome/browser/themes/browser_theme_provider.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-
-@interface BookmarkBarView (Private)
-- (void)themeDidChangeNotification:(NSNotification*)aNotification;
-- (void)updateTheme:(ThemeProvider*)themeProvider;
-@end
-
-@implementation BookmarkBarView
-
-@synthesize dropIndicatorShown = dropIndicatorShown_;
-@synthesize dropIndicatorPosition = dropIndicatorPosition_;
-@synthesize noItemContainer = noItemContainer_;
-
-- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- // This probably isn't strictly necessary, but can't hurt.
- [self unregisterDraggedTypes];
- [super dealloc];
-
- // To be clear, our controller_ is an IBOutlet and owns us, so we
- // don't deallocate it explicitly. It is owned by the browser
- // window controller, so gets deleted with a browser window is
- // closed.
-}
-
-- (void)awakeFromNib {
- NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
- [defaultCenter addObserver:self
- selector:@selector(themeDidChangeNotification:)
- name:kBrowserThemeDidChangeNotification
- object:nil];
-
- DCHECK(controller_) << "Expected this to be hooked up via Interface Builder";
- NSArray* types = [NSArray arrayWithObjects:
- NSStringPboardType,
- NSHTMLPboardType,
- NSURLPboardType,
- kBookmarkButtonDragType,
- kBookmarkDictionaryListPboardType,
- nil];
- [self registerForDraggedTypes:types];
-}
-
-// We need the theme to color the bookmark buttons properly. But our
-// controller desn't have access to it until it's placed in the view
-// hierarchy. This is the spot where we close the loop.
-- (void)viewWillMoveToWindow:(NSWindow*)window {
- ThemeProvider* themeProvider = [window themeProvider];
- [self updateTheme:themeProvider];
- [controller_ updateTheme:themeProvider];
-}
-
-- (void)viewDidMoveToWindow {
- [controller_ viewDidMoveToWindow];
-}
-
-// Called after the current theme has changed.
-- (void)themeDidChangeNotification:(NSNotification*)aNotification {
- ThemeProvider* themeProvider =
- static_cast<ThemeProvider*>([[aNotification object] pointerValue]);
- [self updateTheme:themeProvider];
-}
-
-// Adapt appearance to the current theme. Called after theme changes and before
-// this is shown for the first time.
-- (void)updateTheme:(ThemeProvider*)themeProvider {
- if (!themeProvider)
- return;
-
- NSColor* color =
- themeProvider->GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT,
- true);
- [noItemTextfield_ setTextColor:color];
-}
-
-// Mouse down events on the bookmark bar should not allow dragging the parent
-// window around.
-- (BOOL)mouseDownCanMoveWindow {
- return NO;
-}
-
--(NSTextField*)noItemTextfield {
- return noItemTextfield_;
-}
-
--(NSButton*)importBookmarksButton {
- return importBookmarksButton_;
-}
-
-- (BookmarkBarController*)controller {
- return controller_;
-}
-
--(void)drawRect:(NSRect)dirtyRect {
- [super drawRect:dirtyRect];
-
- // Draw the bookmark-button-dragging drop indicator if necessary.
- if (dropIndicatorShown_) {
- const CGFloat kBarWidth = 1;
- const CGFloat kBarHalfWidth = kBarWidth / 2.0;
- const CGFloat kBarVertPad = 4;
- const CGFloat kBarOpacity = 0.85;
-
- // Prevent the indicator from being clipped on the left.
- CGFloat xLeft = MAX(dropIndicatorPosition_ - kBarHalfWidth, 0);
-
- NSRect uglyBlackBar =
- NSMakeRect(xLeft, kBarVertPad,
- kBarWidth, NSHeight([self bounds]) - 2 * kBarVertPad);
- NSColor* uglyBlackBarColor = [[self window] themeProvider]->
- GetNSColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT, true);
- [[uglyBlackBarColor colorWithAlphaComponent:kBarOpacity] setFill];
- [[NSBezierPath bezierPathWithRect:uglyBlackBar] fill];
- }
-}
-
-// Shim function to assist in unit testing.
-- (BOOL)dragClipboardContainsBookmarks {
- return bookmark_pasteboard_helper_mac::DragClipboardContainsBookmarks();
-}
-
-// NSDraggingDestination methods
-
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- if ([[info draggingPasteboard] dataForType:kBookmarkButtonDragType] ||
- [self dragClipboardContainsBookmarks] ||
- [[info draggingPasteboard] containsURLData]) {
- // We only show the drop indicator if we're not in a position to
- // perform a hover-open since it doesn't make sense to do both.
- BOOL showIt = [controller_ shouldShowIndicatorShownForPoint:
- [info draggingLocation]];
- if (!showIt) {
- if (dropIndicatorShown_) {
- dropIndicatorShown_ = NO;
- [self setNeedsDisplay:YES];
- }
- } else {
- CGFloat x =
- [controller_ indicatorPosForDragToPoint:[info draggingLocation]];
- // Need an update if the indicator wasn't previously shown or if it has
- // moved.
- if (!dropIndicatorShown_ || dropIndicatorPosition_ != x) {
- dropIndicatorShown_ = YES;
- dropIndicatorPosition_ = x;
- [self setNeedsDisplay:YES];
- }
- }
-
- [controller_ draggingEntered:info]; // allow hover-open to work.
- return [info draggingSource] ? NSDragOperationMove : NSDragOperationCopy;
- }
- return NSDragOperationNone;
-}
-
-- (void)draggingExited:(id<NSDraggingInfo>)info {
- // Regardless of the type of dragging which ended, we need to get rid of the
- // drop indicator if one was shown.
- if (dropIndicatorShown_) {
- dropIndicatorShown_ = NO;
- [self setNeedsDisplay:YES];
- }
-}
-
-- (void)draggingEnded:(id<NSDraggingInfo>)info {
- // For now, we just call |-draggingExited:|.
- [self draggingExited:info];
-}
-
-- (BOOL)wantsPeriodicDraggingUpdates {
- // TODO(port): This should probably return |YES| and the controller should
- // slide the existing bookmark buttons interactively to the side to make
- // room for the about-to-be-dropped bookmark.
- return NO;
-}
-
-- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)info {
- // For now it's the same as draggingEntered:.
- // TODO(jrg): once we return YES for wantsPeriodicDraggingUpdates,
- // this should ping the controller_ to perform animations.
- return [self draggingEntered:info];
-}
-
-- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)info {
- return YES;
-}
-
-// Implement NSDraggingDestination protocol method
-// performDragOperation: for URLs.
-- (BOOL)performDragOperationForURL:(id<NSDraggingInfo>)info {
- NSPasteboard* pboard = [info draggingPasteboard];
- DCHECK([pboard containsURLData]);
-
- NSArray* urls = nil;
- NSArray* titles = nil;
- [pboard getURLs:&urls andTitles:&titles convertingFilenames:YES];
-
- return [controller_ addURLs:urls
- withTitles:titles
- at:[info draggingLocation]];
-}
-
-// Implement NSDraggingDestination protocol method
-// performDragOperation: for bookmark buttons.
-- (BOOL)performDragOperationForBookmarkButton:(id<NSDraggingInfo>)info {
- BOOL rtn = NO;
- NSData* data = [[info draggingPasteboard]
- dataForType:kBookmarkButtonDragType];
- // [info draggingSource] is nil if not the same application.
- if (data && [info draggingSource]) {
- BookmarkButton* button = nil;
- [data getBytes:&button length:sizeof(button)];
- BOOL copy = !([info draggingSourceOperationMask] & NSDragOperationMove);
- rtn = [controller_ dragButton:button
- to:[info draggingLocation]
- copy:copy];
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_DragEnd"));
- }
- return rtn;
-}
-
-- (BOOL)performDragOperation:(id<NSDraggingInfo>)info {
- if ([controller_ dragBookmarkData:info])
- return YES;
- NSPasteboard* pboard = [info draggingPasteboard];
- if ([pboard dataForType:kBookmarkButtonDragType]) {
- if ([self performDragOperationForBookmarkButton:info])
- return YES;
- // Fall through....
- }
- if ([pboard containsURLData]) {
- if ([self performDragOperationForURL:info])
- return YES;
- }
- return NO;
-}
-
-- (void)setController:(id)controller {
- controller_ = controller;
-}
-
-- (ViewID)viewID {
- return VIEW_ID_BOOKMARK_BAR;
-}
-
-@end // @implementation BookmarkBarView
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_view_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_view_unittest.mm
deleted file mode 100644
index 3d7725d..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bar_view_unittest.mm
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_view.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/cocoa/url_drop_target.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-
-namespace {
- const CGFloat kFakeIndicatorPos = 7.0;
-};
-
-// Fake DraggingInfo, fake BookmarkBarController, fake NSPasteboard...
-@interface FakeBookmarkDraggingInfo : NSObject {
- @public
- BOOL dragButtonToPong_;
- BOOL dragURLsPong_;
- BOOL dragBookmarkDataPong_;
- BOOL dropIndicatorShown_;
- BOOL draggingEnteredCalled_;
- // Only mock one type of drag data at a time.
- NSString* dragDataType_;
-}
-@property (nonatomic) BOOL dropIndicatorShown;
-@property (nonatomic) BOOL draggingEnteredCalled;
-@property (nonatomic, copy) NSString* dragDataType;
-@end
-
-@implementation FakeBookmarkDraggingInfo
-
-@synthesize dropIndicatorShown = dropIndicatorShown_;
-@synthesize draggingEnteredCalled = draggingEnteredCalled_;
-@synthesize dragDataType = dragDataType_;
-
-- (id)init {
- if ((self = [super init])) {
- dropIndicatorShown_ = YES;
- }
- return self;
-}
-
-- (void)dealloc {
- [dragDataType_ release];
- [super dealloc];
-}
-
-- (void)reset {
- [dragDataType_ release];
- dragDataType_ = nil;
- dragButtonToPong_ = NO;
- dragURLsPong_ = NO;
- dragBookmarkDataPong_ = NO;
- dropIndicatorShown_ = YES;
- draggingEnteredCalled_ = NO;
-}
-
-// NSDragInfo mocking functions.
-
-- (id)draggingPasteboard {
- return self;
-}
-
-// So we can look local.
-- (id)draggingSource {
- return self;
-}
-
-- (NSDragOperation)draggingSourceOperationMask {
- return NSDragOperationCopy | NSDragOperationMove;
-}
-
-- (NSPoint)draggingLocation {
- return NSMakePoint(10, 10);
-}
-
-// NSPasteboard mocking functions.
-
-- (BOOL)containsURLData {
- NSArray* urlTypes = [URLDropTargetHandler handledDragTypes];
- if (dragDataType_)
- return [urlTypes containsObject:dragDataType_];
- return NO;
-}
-
-- (NSData*)dataForType:(NSString*)type {
- if (dragDataType_ && [dragDataType_ isEqualToString:type])
- return [NSData data]; // Return something, anything.
- return nil;
-}
-
-// Fake a controller for callback ponging
-
-- (BOOL)dragButton:(BookmarkButton*)button to:(NSPoint)point copy:(BOOL)copy {
- dragButtonToPong_ = YES;
- return YES;
-}
-
-- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point {
- dragURLsPong_ = YES;
- return YES;
-}
-
-- (void)getURLs:(NSArray**)outUrls
- andTitles:(NSArray**)outTitles
- convertingFilenames:(BOOL)convertFilenames {
-}
-
-- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info {
- dragBookmarkDataPong_ = YES;
- return NO;
-}
-
-// Confirm the pongs.
-
-- (BOOL)dragButtonToPong {
- return dragButtonToPong_;
-}
-
-- (BOOL)dragURLsPong {
- return dragURLsPong_;
-}
-
-- (BOOL)dragBookmarkDataPong {
- return dragBookmarkDataPong_;
-}
-
-- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point {
- return kFakeIndicatorPos;
-}
-
-- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point {
- return dropIndicatorShown_;
-}
-
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info {
- draggingEnteredCalled_ = YES;
- return NSDragOperationNone;
-}
-
-@end
-
-namespace {
-
-class BookmarkBarViewTest : public CocoaTest {
- public:
- virtual void SetUp() {
- CocoaTest::SetUp();
- view_.reset([[BookmarkBarView alloc] init]);
- }
-
- scoped_nsobject<BookmarkBarView> view_;
-};
-
-TEST_F(BookmarkBarViewTest, CanDragWindow) {
- EXPECT_FALSE([view_ mouseDownCanMoveWindow]);
-}
-
-TEST_F(BookmarkBarViewTest, BookmarkButtonDragAndDrop) {
- scoped_nsobject<FakeBookmarkDraggingInfo>
- info([[FakeBookmarkDraggingInfo alloc] init]);
- [view_ setController:info.get()];
- [info reset];
-
- [info setDragDataType:kBookmarkButtonDragType];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([view_ performDragOperation:(id)info.get()]);
- EXPECT_TRUE([info dragButtonToPong]);
- EXPECT_FALSE([info dragURLsPong]);
- EXPECT_TRUE([info dragBookmarkDataPong]);
-}
-
-TEST_F(BookmarkBarViewTest, URLDragAndDrop) {
- scoped_nsobject<FakeBookmarkDraggingInfo>
- info([[FakeBookmarkDraggingInfo alloc] init]);
- [view_ setController:info.get()];
- [info reset];
-
- NSArray* dragTypes = [URLDropTargetHandler handledDragTypes];
- for (NSString* type in dragTypes) {
- [info setDragDataType:type];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([view_ performDragOperation:(id)info.get()]);
- EXPECT_FALSE([info dragButtonToPong]);
- EXPECT_TRUE([info dragURLsPong]);
- EXPECT_TRUE([info dragBookmarkDataPong]);
- [info reset];
- }
-}
-
-TEST_F(BookmarkBarViewTest, BookmarkButtonDropIndicator) {
- scoped_nsobject<FakeBookmarkDraggingInfo>
- info([[FakeBookmarkDraggingInfo alloc] init]);
- [view_ setController:info.get()];
-
- [info reset];
- [info setDragDataType:kBookmarkButtonDragType];
- EXPECT_FALSE([info draggingEnteredCalled]);
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_TRUE([info draggingEnteredCalled]); // Ensure controller pinged.
- EXPECT_TRUE([view_ dropIndicatorShown]);
- EXPECT_EQ([view_ dropIndicatorPosition], kFakeIndicatorPos);
-
- [info setDropIndicatorShown:NO];
- EXPECT_EQ([view_ draggingEntered:(id)info.get()], NSDragOperationMove);
- EXPECT_FALSE([view_ dropIndicatorShown]);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h
deleted file mode 100644
index 9ceee17..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#import "base/cocoa_protocols_mac.h"
-#include "base/scoped_ptr.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h"
-
-class BookmarkBubbleNotificationBridge;
-class BookmarkModel;
-class BookmarkNode;
-@class BookmarkBubbleController;
-@class InfoBubbleView;
-
-
-// Controller for the bookmark bubble. The bookmark bubble is a
-// bubble that pops up when clicking on the STAR next to the URL to
-// add or remove it as a bookmark. This bubble allows for editing of
-// the bookmark in various ways (name, folder, etc.)
-@interface BookmarkBubbleController : NSWindowController<NSWindowDelegate> {
- @private
- NSWindow* parentWindow_; // weak
-
- // Both weak; owned by the current browser's profile
- BookmarkModel* model_; // weak
- const BookmarkNode* node_; // weak
-
- // The bookmark node whose button we asked to pulse.
- const BookmarkNode* pulsingBookmarkNode_; // weak
-
- BOOL alreadyBookmarked_;
-
- // Ping me when the bookmark model changes out from under us.
- scoped_ptr<BookmarkModelObserverForCocoa> bookmark_observer_;
-
- // Ping me when other Chrome things change out from under us.
- scoped_ptr<BookmarkBubbleNotificationBridge> chrome_observer_;
-
- IBOutlet NSTextField* bigTitle_; // "Bookmark" or "Bookmark Added!"
- IBOutlet NSTextField* nameTextField_;
- IBOutlet NSPopUpButton* folderPopUpButton_;
- IBOutlet InfoBubbleView* bubble_; // to set arrow position
-}
-
-@property (readonly, nonatomic) const BookmarkNode* node;
-
-// |node| is the bookmark node we edit in this bubble.
-// |alreadyBookmarked| tells us if the node was bookmarked before the
-// user clicked on the star. (if NO, this is a brand new bookmark).
-// The owner of this object is responsible for showing the bubble if
-// it desires it to be visible on the screen. It is not shown by the
-// init routine. Closing of the window happens implicitly on dealloc.
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- model:(BookmarkModel*)model
- node:(const BookmarkNode*)node
- alreadyBookmarked:(BOOL)alreadyBookmarked;
-
-// Actions for buttons in the dialog.
-- (IBAction)ok:(id)sender;
-- (IBAction)remove:(id)sender;
-- (IBAction)cancel:(id)sender;
-
-// These actions send a -editBookmarkNode: action up the responder chain.
-- (IBAction)edit:(id)sender;
-- (IBAction)folderChanged:(id)sender;
-
-@end
-
-
-// Exposed only for unit testing.
-@interface BookmarkBubbleController(ExposedForUnitTesting)
-- (void)addFolderNodes:(const BookmarkNode*)parent
- toPopUpButton:(NSPopUpButton*)button
- indentation:(int)indentation;
-- (void)setTitle:(NSString*)title parentFolder:(const BookmarkNode*)parent;
-- (void)setParentFolderSelection:(const BookmarkNode*)parent;
-+ (NSString*)chooseAnotherFolderString;
-- (NSPopUpButton*)folderPopUpButton;
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.mm
deleted file mode 100644
index d367ff9..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.mm
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h"
-
-#include "app/l10n_util_mac.h"
-#include "base/mac_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h" // TODO(viettrungluu): remove
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/info_bubble_view.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-#include "chrome/common/notification_service.h"
-#include "grit/generated_resources.h"
-
-
-// Simple class to watch for tab creation/destruction and close the bubble.
-// Bridge between Chrome-style notifications and ObjC-style notifications.
-class BookmarkBubbleNotificationBridge : public NotificationObserver {
- public:
- BookmarkBubbleNotificationBridge(BookmarkBubbleController* controller,
- SEL selector);
- virtual ~BookmarkBubbleNotificationBridge() {}
- void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
- private:
- NotificationRegistrar registrar_;
- BookmarkBubbleController* controller_; // weak; owns us.
- SEL selector_; // SEL sent to controller_ on notification.
-};
-
-BookmarkBubbleNotificationBridge::BookmarkBubbleNotificationBridge(
- BookmarkBubbleController* controller, SEL selector)
- : controller_(controller), selector_(selector) {
- // registrar_ will automatically RemoveAll() when destroyed so we
- // don't need to do so explicitly.
- registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
- NotificationService::AllSources());
- registrar_.Add(this, NotificationType::TAB_CLOSED,
- NotificationService::AllSources());
-}
-
-// At this time all notifications instigate the same behavior (go
-// away) so we don't bother checking which notification came in.
-void BookmarkBubbleNotificationBridge::Observe(
- NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- [controller_ performSelector:selector_ withObject:controller_];
-}
-
-
-// An object to represent the ChooseAnotherFolder item in the pop up.
-@interface ChooseAnotherFolder : NSObject
-@end
-
-@implementation ChooseAnotherFolder
-@end
-
-@interface BookmarkBubbleController (PrivateAPI)
-- (void)updateBookmarkNode;
-- (void)fillInFolderList;
-- (void)parentWindowWillClose:(NSNotification*)notification;
-@end
-
-@implementation BookmarkBubbleController
-
-@synthesize node = node_;
-
-+ (id)chooseAnotherFolderObject {
- // Singleton object to act as a representedObject for the "choose another
- // folder" item in the pop up.
- static ChooseAnotherFolder* object = nil;
- if (!object) {
- object = [[ChooseAnotherFolder alloc] init];
- }
- return object;
-}
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- model:(BookmarkModel*)model
- node:(const BookmarkNode*)node
- alreadyBookmarked:(BOOL)alreadyBookmarked {
- NSString* nibPath =
- [mac_util::MainAppBundle() pathForResource:@"BookmarkBubble"
- ofType:@"nib"];
- if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
- parentWindow_ = parentWindow;
- model_ = model;
- node_ = node;
- alreadyBookmarked_ = alreadyBookmarked;
-
- // Watch to see if the parent window closes, and if so, close this one.
- NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
- selector:@selector(parentWindowWillClose:)
- name:NSWindowWillCloseNotification
- object:parentWindow_];
- }
- return self;
-}
-
-- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super dealloc];
-}
-
-// If this is a new bookmark somewhere visible (e.g. on the bookmark
-// bar), pulse it. Else, call ourself recursively with our parent
-// until we find something visible to pulse.
-- (void)startPulsingBookmarkButton:(const BookmarkNode*)node {
- while (node) {
- if ((node->GetParent() == model_->GetBookmarkBarNode()) ||
- (node == model_->other_node())) {
- pulsingBookmarkNode_ = node;
- NSValue *value = [NSValue valueWithPointer:node];
- NSDictionary *dict = [NSDictionary
- dictionaryWithObjectsAndKeys:value,
- bookmark_button::kBookmarkKey,
- [NSNumber numberWithBool:YES],
- bookmark_button::kBookmarkPulseFlagKey,
- nil];
- [[NSNotificationCenter defaultCenter]
- postNotificationName:bookmark_button::kPulseBookmarkButtonNotification
- object:self
- userInfo:dict];
- return;
- }
- node = node->GetParent();
- }
-}
-
-- (void)stopPulsingBookmarkButton {
- if (!pulsingBookmarkNode_)
- return;
- NSValue *value = [NSValue valueWithPointer:pulsingBookmarkNode_];
- pulsingBookmarkNode_ = NULL;
- NSDictionary *dict = [NSDictionary
- dictionaryWithObjectsAndKeys:value,
- bookmark_button::kBookmarkKey,
- [NSNumber numberWithBool:NO],
- bookmark_button::kBookmarkPulseFlagKey,
- nil];
- [[NSNotificationCenter defaultCenter]
- postNotificationName:bookmark_button::kPulseBookmarkButtonNotification
- object:self
- userInfo:dict];
-}
-
-// Close the bookmark bubble without changing anything. Unlike a
-// typical dialog's OK/Cancel, where Cancel is "do nothing", all
-// buttons on the bubble have the capacity to change the bookmark
-// model. This is an IBOutlet-looking entry point to remove the
-// dialog without touching the model.
-- (void)dismissWithoutEditing:(id)sender {
- [self close];
-}
-
-- (void)parentWindowWillClose:(NSNotification*)notification {
- [self close];
-}
-
-- (void)windowWillClose:(NSNotification*)notification {
- // We caught a close so we don't need to watch for the parent closing.
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- bookmark_observer_.reset(NULL);
- chrome_observer_.reset(NULL);
- [self stopPulsingBookmarkButton];
- [self autorelease];
-}
-
-// We want this to be a child of a browser window. addChildWindow:
-// (called from this function) will bring the window on-screen;
-// unfortunately, [NSWindowController showWindow:] will also bring it
-// on-screen (but will cause unexpected changes to the window's
-// position). We cannot have an addChildWindow: and a subsequent
-// showWindow:. Thus, we have our own version.
-- (void)showWindow:(id)sender {
- BrowserWindowController* bwc =
- [BrowserWindowController browserWindowControllerForWindow:parentWindow_];
- [bwc lockBarVisibilityForOwner:self withAnimation:NO delay:NO];
- NSWindow* window = [self window]; // completes nib load
- [bubble_ setArrowLocation:info_bubble::kTopRight];
- // Insure decent positioning even in the absence of a browser controller,
- // which will occur for some unit tests.
- NSPoint arrowtip = bwc ? [bwc bookmarkBubblePoint] :
- NSMakePoint([window frame].size.width, [window frame].size.height);
- NSPoint origin = [parentWindow_ convertBaseToScreen:arrowtip];
- NSPoint bubbleArrowtip = [bubble_ arrowTip];
- bubbleArrowtip = [bubble_ convertPoint:bubbleArrowtip toView:nil];
- origin.y -= bubbleArrowtip.y;
- origin.x -= bubbleArrowtip.x;
- [window setFrameOrigin:origin];
- [parentWindow_ addChildWindow:window ordered:NSWindowAbove];
- // Default is IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK; "Bookmark".
- // If adding for the 1st time the string becomes "Bookmark Added!"
- if (!alreadyBookmarked_) {
- NSString* title =
- l10n_util::GetNSString(IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED);
- [bigTitle_ setStringValue:title];
- }
-
- [self fillInFolderList];
-
- // Ping me when things change out from under us. Unlike a normal
- // dialog, the bookmark bubble's cancel: means "don't add this as a
- // bookmark", not "cancel editing". We must take extra care to not
- // touch the bookmark in this selector.
- bookmark_observer_.reset(new BookmarkModelObserverForCocoa(
- node_, model_,
- self,
- @selector(dismissWithoutEditing:)));
- chrome_observer_.reset(new BookmarkBubbleNotificationBridge(
- self, @selector(dismissWithoutEditing:)));
-
- // Pulse something interesting on the bookmark bar.
- [self startPulsingBookmarkButton:node_];
-
- [window makeKeyAndOrderFront:self];
-}
-
-- (void)close {
- [[BrowserWindowController browserWindowControllerForWindow:parentWindow_]
- releaseBarVisibilityForOwner:self withAnimation:YES delay:NO];
- [parentWindow_ removeChildWindow:[self window]];
-
- // If you quit while the bubble is open, sometimes we get a
- // DidResignKey before we get our parent's WindowWillClose and
- // sometimes not. We protect against a multiple close (or reference
- // to parentWindow_ at a bad time) by clearing it out once we're
- // done, and by removing ourself from future notifications.
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:NSWindowWillCloseNotification
- object:parentWindow_];
- parentWindow_ = nil;
-
- [super close];
-}
-
-// Shows the bookmark editor sheet for more advanced editing.
-- (void)showEditor {
- [self ok:self];
- // Send the action up through the responder chain.
- [NSApp sendAction:@selector(editBookmarkNode:) to:nil from:self];
-}
-
-- (IBAction)edit:(id)sender {
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Edit"),
- model_->profile());
- [self showEditor];
-}
-
-- (IBAction)ok:(id)sender {
- [self stopPulsingBookmarkButton]; // before parent changes
- [self updateBookmarkNode];
- [self close];
-}
-
-// By implementing this, ESC causes the window to go away. If clicking the
-// star was what prompted this bubble to appear (i.e., not already bookmarked),
-// remove the bookmark.
-- (IBAction)cancel:(id)sender {
- if (!alreadyBookmarked_) {
- // |-remove:| calls |-close| so don't do it.
- [self remove:sender];
- } else {
- [self ok:sender];
- }
-}
-
-- (IBAction)remove:(id)sender {
- [self stopPulsingBookmarkButton];
- // TODO(viettrungluu): get rid of conversion and utf_string_conversions.h.
- model_->SetURLStarred(node_->GetURL(), node_->GetTitle(), false);
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Unstar"),
- model_->profile());
- node_ = NULL; // no longer valid
- [self ok:sender];
-}
-
-// The controller is the target of the pop up button box action so it can
-// handle when "choose another folder" was picked.
-- (IBAction)folderChanged:(id)sender {
- DCHECK([sender isEqual:folderPopUpButton_]);
- // It is possible that due to model change our parent window has been closed
- // but the popup is still showing and able to notify the controller of a
- // folder change. We ignore the sender in this case.
- if (!parentWindow_)
- return;
- NSMenuItem* selected = [folderPopUpButton_ selectedItem];
- ChooseAnotherFolder* chooseItem = [[self class] chooseAnotherFolderObject];
- if ([[selected representedObject] isEqual:chooseItem]) {
- UserMetrics::RecordAction(
- UserMetricsAction("BookmarkBubble_EditFromCombobox"),
- model_->profile());
- [self showEditor];
- }
-}
-
-// The controller is the delegate of the window so it receives did resign key
-// notifications. When key is resigned mirror Windows behavior and close the
-// window.
-- (void)windowDidResignKey:(NSNotification*)notification {
- NSWindow* window = [self window];
- DCHECK_EQ([notification object], window);
- if ([window isVisible]) {
- // If the window isn't visible, it is already closed, and this notification
- // has been sent as part of the closing operation, so no need to close.
- [self ok:self];
- }
-}
-
-// Look at the dialog; if the user has changed anything, update the
-// bookmark node to reflect this.
-- (void)updateBookmarkNode {
- if (!node_) return;
-
- // First the title...
- NSString* oldTitle = base::SysUTF16ToNSString(node_->GetTitle());
- NSString* newTitle = [nameTextField_ stringValue];
- if (![oldTitle isEqual:newTitle]) {
- model_->SetTitle(node_, base::SysNSStringToUTF16(newTitle));
- UserMetrics::RecordAction(
- UserMetricsAction("BookmarkBubble_ChangeTitleInBubble"),
- model_->profile());
- }
- // Then the parent folder.
- const BookmarkNode* oldParent = node_->GetParent();
- NSMenuItem* selectedItem = [folderPopUpButton_ selectedItem];
- id representedObject = [selectedItem representedObject];
- if ([representedObject isEqual:[[self class] chooseAnotherFolderObject]]) {
- // "Choose another folder..."
- return;
- }
- const BookmarkNode* newParent =
- static_cast<const BookmarkNode*>([representedObject pointerValue]);
- DCHECK(newParent);
- if (oldParent != newParent) {
- int index = newParent->GetChildCount();
- model_->Move(node_, newParent, index);
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_ChangeParent"),
- model_->profile());
- }
-}
-
-// Fill in all information related to the folder pop up button.
-- (void)fillInFolderList {
- [nameTextField_ setStringValue:base::SysUTF16ToNSString(node_->GetTitle())];
- DCHECK([folderPopUpButton_ numberOfItems] == 0);
- [self addFolderNodes:model_->root_node()
- toPopUpButton:folderPopUpButton_
- indentation:0];
- NSMenu* menu = [folderPopUpButton_ menu];
- NSString* title = [[self class] chooseAnotherFolderString];
- NSMenuItem *item = [menu addItemWithTitle:title
- action:NULL
- keyEquivalent:@""];
- ChooseAnotherFolder* obj = [[self class] chooseAnotherFolderObject];
- [item setRepresentedObject:obj];
- // Finally, select the current parent.
- NSValue* parentValue = [NSValue valueWithPointer:node_->GetParent()];
- NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue];
- [folderPopUpButton_ selectItemAtIndex:idx];
-}
-
-@end // BookmarkBubbleController
-
-
-@implementation BookmarkBubbleController(ExposedForUnitTesting)
-
-+ (NSString*)chooseAnotherFolderString {
- return l10n_util::GetNSStringWithFixup(
- IDS_BOOMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER);
-}
-
-// For the given folder node, walk the tree and add folder names to
-// the given pop up button.
-- (void)addFolderNodes:(const BookmarkNode*)parent
- toPopUpButton:(NSPopUpButton*)button
- indentation:(int)indentation {
- if (!model_->is_root(parent)) {
- NSString* title = base::SysUTF16ToNSString(parent->GetTitle());
- NSMenu* menu = [button menu];
- NSMenuItem* item = [menu addItemWithTitle:title
- action:NULL
- keyEquivalent:@""];
- [item setRepresentedObject:[NSValue valueWithPointer:parent]];
- [item setIndentationLevel:indentation];
- ++indentation;
- }
- for (int i = 0; i < parent->GetChildCount(); i++) {
- const BookmarkNode* child = parent->GetChild(i);
- if (child->is_folder())
- [self addFolderNodes:child
- toPopUpButton:button
- indentation:indentation];
- }
-}
-
-- (void)setTitle:(NSString*)title parentFolder:(const BookmarkNode*)parent {
- [nameTextField_ setStringValue:title];
- [self setParentFolderSelection:parent];
-}
-
-// Pick a specific parent node in the selection by finding the right
-// pop up button index.
-- (void)setParentFolderSelection:(const BookmarkNode*)parent {
- // Expectation: There is a parent mapping for all items in the
- // folderPopUpButton except the last one ("Choose another folder...").
- NSMenu* menu = [folderPopUpButton_ menu];
- NSValue* parentValue = [NSValue valueWithPointer:parent];
- NSInteger idx = [menu indexOfItemWithRepresentedObject:parentValue];
- DCHECK(idx != -1);
- [folderPopUpButton_ selectItemAtIndex:idx];
-}
-
-- (NSPopUpButton*)folderPopUpButton {
- return folderPopUpButton_;
-}
-
-@end // implementation BookmarkBubbleController(ExposedForUnitTesting)
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
deleted file mode 100644
index 4a5b600..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_bubble_controller_unittest.mm
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/basictypes.h"
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bubble_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#include "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/cocoa/info_bubble_window.h"
-#include "chrome/common/notification_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-// Watch for bookmark pulse notifications so we can confirm they were sent.
-@interface BookmarkPulseObserver : NSObject {
- int notifications_;
-}
-@property (assign, nonatomic) int notifications;
-@end
-
-
-@implementation BookmarkPulseObserver
-
-@synthesize notifications = notifications_;
-
-- (id)init {
- if ((self = [super init])) {
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(pulseBookmarkNotification:)
- name:bookmark_button::kPulseBookmarkButtonNotification
- object:nil];
- }
- return self;
-}
-
-- (void)pulseBookmarkNotification:(NSNotificationCenter *)notification {
- notifications_++;
-}
-
-- (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super dealloc];
-}
-
-@end
-
-
-namespace {
-
-class BookmarkBubbleControllerTest : public CocoaTest {
- public:
- static int edits_;
- BrowserTestHelper helper_;
- BookmarkBubbleController* controller_;
-
- BookmarkBubbleControllerTest() : controller_(nil) {
- edits_ = 0;
- }
-
- virtual void TearDown() {
- [controller_ close];
- CocoaTest::TearDown();
- }
-
- // Returns a controller but ownership not transferred.
- // Only one of these will be valid at a time.
- BookmarkBubbleController* ControllerForNode(const BookmarkNode* node) {
- if (controller_ && !IsWindowClosing()) {
- [controller_ close];
- controller_ = nil;
- }
- controller_ = [[BookmarkBubbleController alloc]
- initWithParentWindow:test_window()
- model:helper_.profile()->GetBookmarkModel()
- node:node
- alreadyBookmarked:YES];
- EXPECT_TRUE([controller_ window]);
- // The window must be gone or we'll fail a unit test with windows left open.
- [static_cast<InfoBubbleWindow*>([controller_ window]) setDelayOnClose:NO];
- [controller_ showWindow:nil];
- return controller_;
- }
-
- BookmarkModel* GetBookmarkModel() {
- return helper_.profile()->GetBookmarkModel();
- }
-
- bool IsWindowClosing() {
- return [static_cast<InfoBubbleWindow*>([controller_ window]) isClosing];
- }
-};
-
-// static
-int BookmarkBubbleControllerTest::edits_;
-
-// Confirm basics about the bubble window (e.g. that it is inside the
-// parent window)
-TEST_F(BookmarkBubbleControllerTest, TestBubbleWindow) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
- NSWindow* window = [controller window];
- EXPECT_TRUE(window);
- EXPECT_TRUE(NSContainsRect([test_window() frame],
- [window frame]));
-}
-
-// Test that we can handle closing the parent window
-TEST_F(BookmarkBubbleControllerTest, TestClosingParentWindow) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
- NSWindow* window = [controller window];
- EXPECT_TRUE(window);
- base::mac::ScopedNSAutoreleasePool pool;
- [test_window() performClose:NSApp];
-}
-
-
-// Confirm population of folder list
-TEST_F(BookmarkBubbleControllerTest, TestFillInFolder) {
- // Create some folders, including a nested folder
- BookmarkModel* model = GetBookmarkModel();
- EXPECT_TRUE(model);
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("one"));
- EXPECT_TRUE(node1);
- const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1,
- ASCIIToUTF16("two"));
- EXPECT_TRUE(node2);
- const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2,
- ASCIIToUTF16("three"));
- EXPECT_TRUE(node3);
- const BookmarkNode* node4 = model->AddGroup(node2, 0, ASCIIToUTF16("sub"));
- EXPECT_TRUE(node4);
- const BookmarkNode* node5 = model->AddURL(node1, 0, ASCIIToUTF16("title1"),
- GURL("http://www.google.com"));
- EXPECT_TRUE(node5);
- const BookmarkNode* node6 = model->AddURL(node3, 0, ASCIIToUTF16("title2"),
- GURL("http://www.google.com"));
- EXPECT_TRUE(node6);
- const BookmarkNode* node7 = model->AddURL(node4, 0, ASCIIToUTF16("title3"),
- GURL("http://www.google.com/reader"));
- EXPECT_TRUE(node7);
-
- BookmarkBubbleController* controller = ControllerForNode(node4);
- EXPECT_TRUE(controller);
-
- NSArray* titles =
- [[[controller folderPopUpButton] itemArray] valueForKey:@"title"];
- EXPECT_TRUE([titles containsObject:@"one"]);
- EXPECT_TRUE([titles containsObject:@"two"]);
- EXPECT_TRUE([titles containsObject:@"three"]);
- EXPECT_TRUE([titles containsObject:@"sub"]);
- EXPECT_FALSE([titles containsObject:@"title1"]);
- EXPECT_FALSE([titles containsObject:@"title2"]);
-}
-
-// Confirm ability to handle folders with blank name.
-TEST_F(BookmarkBubbleControllerTest, TestFolderWithBlankName) {
- // Create some folders, including a nested folder
- BookmarkModel* model = GetBookmarkModel();
- EXPECT_TRUE(model);
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("one"));
- EXPECT_TRUE(node1);
- const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1,
- ASCIIToUTF16(""));
- EXPECT_TRUE(node2);
- const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2,
- ASCIIToUTF16("three"));
- EXPECT_TRUE(node3);
- const BookmarkNode* node2_1 = model->AddURL(node2, 0, ASCIIToUTF16("title1"),
- GURL("http://www.google.com"));
- EXPECT_TRUE(node2_1);
-
- BookmarkBubbleController* controller = ControllerForNode(node1);
- EXPECT_TRUE(controller);
-
- // One of the items should be blank and its node should be node2.
- NSArray* items = [[controller folderPopUpButton] itemArray];
- EXPECT_GT([items count], 4U);
- BOOL blankFolderFound = NO;
- for (NSMenuItem* item in [[controller folderPopUpButton] itemArray]) {
- if ([[item title] length] == 0 &&
- static_cast<const BookmarkNode*>([[item representedObject]
- pointerValue]) == node2) {
- blankFolderFound = YES;
- break;
- }
- }
- EXPECT_TRUE(blankFolderFound);
-}
-
-
-// Click on edit; bubble gets closed.
-TEST_F(BookmarkBubbleControllerTest, TestEdit) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
-
- EXPECT_EQ(edits_, 0);
- EXPECT_FALSE(IsWindowClosing());
- [controller edit:controller];
- EXPECT_EQ(edits_, 1);
- EXPECT_TRUE(IsWindowClosing());
-}
-
-// CallClose; bubble gets closed.
-// Also confirm pulse notifications get sent.
-TEST_F(BookmarkBubbleControllerTest, TestClose) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(
- model->GetBookmarkBarNode(), 0, ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
- EXPECT_EQ(edits_, 0);
-
- scoped_nsobject<BookmarkPulseObserver> observer([[BookmarkPulseObserver alloc]
- init]);
- EXPECT_EQ([observer notifications], 0);
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
- EXPECT_FALSE(IsWindowClosing());
- EXPECT_EQ([observer notifications], 1);
- [controller ok:controller];
- EXPECT_EQ(edits_, 0);
- EXPECT_TRUE(IsWindowClosing());
- EXPECT_EQ([observer notifications], 2);
-}
-
-// User changes title and parent folder in the UI
-TEST_F(BookmarkBubbleControllerTest, TestUserEdit) {
- BookmarkModel* model = GetBookmarkModel();
- EXPECT_TRUE(model);
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- const BookmarkNode* node = model->AddURL(bookmarkBarNode,
- 0,
- ASCIIToUTF16("short-title"),
- GURL("http://www.google.com"));
- const BookmarkNode* grandma = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("grandma"));
- EXPECT_TRUE(grandma);
- const BookmarkNode* grandpa = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("grandpa"));
- EXPECT_TRUE(grandpa);
-
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
-
- // simulate a user edit
- [controller setTitle:@"oops" parentFolder:grandma];
- [controller edit:controller];
-
- // Make sure bookmark has changed
- EXPECT_EQ(node->GetTitle(), ASCIIToUTF16("oops"));
- EXPECT_EQ(node->GetParent()->GetTitle(), ASCIIToUTF16("grandma"));
-}
-
-// Confirm happiness with parent nodes that have the same name.
-TEST_F(BookmarkBubbleControllerTest, TestNewParentSameName) {
- BookmarkModel* model = GetBookmarkModel();
- EXPECT_TRUE(model);
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- for (int i=0; i<2; i++) {
- const BookmarkNode* node = model->AddURL(bookmarkBarNode,
- 0,
- ASCIIToUTF16("short-title"),
- GURL("http://www.google.com"));
- EXPECT_TRUE(node);
- const BookmarkNode* group = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("NAME"));
- EXPECT_TRUE(group);
- group = model->AddGroup(bookmarkBarNode, 0, ASCIIToUTF16("NAME"));
- EXPECT_TRUE(group);
- group = model->AddGroup(bookmarkBarNode, 0, ASCIIToUTF16("NAME"));
- EXPECT_TRUE(group);
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
-
- // simulate a user edit
- [controller setParentFolderSelection:bookmarkBarNode->GetChild(i)];
- [controller edit:controller];
-
- // Make sure bookmark has changed, and that the parent is what we
- // expect. This proves nobody did searching based on name.
- EXPECT_EQ(node->GetParent(), bookmarkBarNode->GetChild(i));
- }
-}
-
-// Confirm happiness with nodes with the same Name
-TEST_F(BookmarkBubbleControllerTest, TestDuplicateNodeNames) {
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("NAME"));
- EXPECT_TRUE(node1);
- const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("NAME"));
- EXPECT_TRUE(node2);
- BookmarkBubbleController* controller = ControllerForNode(bookmarkBarNode);
- EXPECT_TRUE(controller);
-
- NSPopUpButton* button = [controller folderPopUpButton];
- [controller setParentFolderSelection:node1];
- NSMenuItem* item = [button selectedItem];
- id itemObject = [item representedObject];
- EXPECT_NSEQ([NSValue valueWithPointer:node1], itemObject);
- [controller setParentFolderSelection:node2];
- item = [button selectedItem];
- itemObject = [item representedObject];
- EXPECT_NSEQ([NSValue valueWithPointer:node2], itemObject);
-}
-
-// Click the "remove" button
-TEST_F(BookmarkBubbleControllerTest, TestRemove) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
- EXPECT_TRUE(model->IsBookmarked(gurl));
-
- [controller remove:controller];
- EXPECT_FALSE(model->IsBookmarked(gurl));
- EXPECT_TRUE(IsWindowClosing());
-}
-
-// Confirm picking "choose another folder" caused edit: to be called.
-TEST_F(BookmarkBubbleControllerTest, PopUpSelectionChanged) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0, ASCIIToUTF16("super-title"),
- gurl);
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
-
- NSPopUpButton* button = [controller folderPopUpButton];
- [button selectItemWithTitle:[[controller class] chooseAnotherFolderString]];
- EXPECT_EQ(edits_, 0);
- [button sendAction:[button action] to:[button target]];
- EXPECT_EQ(edits_, 1);
-}
-
-// Create a controller that simulates the bookmark just now being created by
-// the user clicking the star, then sending the "cancel" command to represent
-// them pressing escape. The bookmark should not be there.
-TEST_F(BookmarkBubbleControllerTest, EscapeRemovesNewBookmark) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
- BookmarkBubbleController* controller =
- [[BookmarkBubbleController alloc]
- initWithParentWindow:test_window()
- model:helper_.profile()->GetBookmarkModel()
- node:node
- alreadyBookmarked:NO]; // The last param is the key difference.
- EXPECT_TRUE([controller window]);
- // Calls release on controller.
- [controller cancel:nil];
- EXPECT_FALSE(model->IsBookmarked(gurl));
-}
-
-// Create a controller where the bookmark already existed prior to clicking
-// the star and test that sending a cancel command doesn't change the state
-// of the bookmark.
-TEST_F(BookmarkBubbleControllerTest, EscapeDoesntTouchExistingBookmark) {
- BookmarkModel* model = GetBookmarkModel();
- GURL gurl("http://www.google.com");
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- gurl);
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
-
- [(id)controller cancel:nil];
- EXPECT_TRUE(model->IsBookmarked(gurl));
-}
-
-// Confirm indentation of items in pop-up menu
-TEST_F(BookmarkBubbleControllerTest, TestMenuIndentation) {
- // Create some folders, including a nested folder
- BookmarkModel* model = GetBookmarkModel();
- EXPECT_TRUE(model);
- const BookmarkNode* bookmarkBarNode = model->GetBookmarkBarNode();
- EXPECT_TRUE(bookmarkBarNode);
- const BookmarkNode* node1 = model->AddGroup(bookmarkBarNode, 0,
- ASCIIToUTF16("one"));
- EXPECT_TRUE(node1);
- const BookmarkNode* node2 = model->AddGroup(bookmarkBarNode, 1,
- ASCIIToUTF16("two"));
- EXPECT_TRUE(node2);
- const BookmarkNode* node2_1 = model->AddGroup(node2, 0,
- ASCIIToUTF16("two dot one"));
- EXPECT_TRUE(node2_1);
- const BookmarkNode* node3 = model->AddGroup(bookmarkBarNode, 2,
- ASCIIToUTF16("three"));
- EXPECT_TRUE(node3);
-
- BookmarkBubbleController* controller = ControllerForNode(node1);
- EXPECT_TRUE(controller);
-
- // Compare the menu item indents against expectations.
- static const int kExpectedIndent[] = {0, 1, 1, 2, 1, 0};
- NSArray* items = [[controller folderPopUpButton] itemArray];
- ASSERT_GE([items count], 6U);
- for(int itemNo = 0; itemNo < 6; itemNo++) {
- NSMenuItem* item = [items objectAtIndex:itemNo];
- EXPECT_EQ(kExpectedIndent[itemNo], [item indentationLevel])
- << "Unexpected indent for menu item #" << itemNo;
- }
-}
-
-// Confirm bubble goes away when a new tab is created.
-TEST_F(BookmarkBubbleControllerTest, BubbleGoesAwayOnNewTab) {
-
- BookmarkModel* model = GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0,
- ASCIIToUTF16("Bookie markie title"),
- GURL("http://www.google.com"));
- EXPECT_EQ(edits_, 0);
-
- BookmarkBubbleController* controller = ControllerForNode(node);
- EXPECT_TRUE(controller);
- EXPECT_FALSE(IsWindowClosing());
-
- // We can't actually create a new tab here, e.g.
- // helper_.browser()->AddTabWithURL(...);
- // Many of our browser objects (Browser, Profile, RequestContext)
- // are "just enough" to run tests without being complete. Instead
- // we fake the notification that would be triggered by a tab
- // creation.
- NotificationService::current()->Notify(
- NotificationType::TAB_CONTENTS_CONNECTED,
- Source<TabContentsDelegate>(NULL),
- Details<TabContents>(NULL));
-
- // Confirm bubble going bye-bye.
- EXPECT_TRUE(IsWindowClosing());
-}
-
-
-} // namespace
-
-@implementation NSApplication (BookmarkBubbleUnitTest)
-// Add handler for the editBookmarkNode: action to NSApp for testing purposes.
-// Normally this would be sent up the responder tree correctly, but since
-// tests run in the background, key window and main window are never set on
-// NSApplication. Adding it to NSApplication directly removes the need for
-// worrying about what the current window with focus is.
-- (void)editBookmarkNode:(id)sender {
- EXPECT_TRUE([sender respondsToSelector:@selector(node)]);
- BookmarkBubbleControllerTest::edits_++;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button.h b/chrome/browser/cocoa/bookmarks/bookmark_button.h
deleted file mode 100644
index 5d8574c..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-#include <vector>
-#import "chrome/browser/cocoa/draggable_button.h"
-#include "webkit/glue/window_open_disposition.h"
-
-@class BookmarkBarFolderController;
-@class BookmarkButton;
-struct BookmarkNodeData;
-class BookmarkModel;
-class BookmarkNode;
-@class BrowserWindowController;
-class ThemeProvider;
-
-// Protocol for a BookmarkButton's delegate, responsible for doing
-// things on behalf of a bookmark button.
-@protocol BookmarkButtonDelegate
-
-// Fill the given pasteboard with appropriate data when the given button is
-// dragged. Since the delegate has no way of providing pasteboard data later,
-// all data must actually be put into the pasteboard and not merely promised.
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button;
-
-// Bookmark buttons pass mouseEntered: and mouseExited: events to
-// their delegate. This allows the delegate to decide (for example)
-// which one, if any, should perform a hover-open.
-- (void)mouseEnteredButton:(id)button event:(NSEvent*)event;
-- (void)mouseExitedButton:(id)button event:(NSEvent*)event;
-
-// Returns YES if a drag operation should lock the fullscreen overlay bar
-// visibility before starting. For example, dragging a bookmark button should
-// not lock the overlay if the bookmark bar is currently showing in detached
-// mode on the NTP.
-- (BOOL)dragShouldLockBarVisibility;
-
-// Returns the top-level window for this button.
-- (NSWindow*)browserWindow;
-
-// Returns YES if the bookmark button can be dragged to the trash, NO otherwise.
-- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button;
-
-// This is called after the user has dropped the bookmark button on the trash.
-// The delegate can use this event to delete the bookmark.
-- (void)didDragBookmarkToTrash:(BookmarkButton*)button;
-
-@end
-
-
-// Protocol to be implemented by controllers that logically own
-// bookmark buttons. The controller may be either an NSViewController
-// or NSWindowController. The BookmarkButton doesn't use this
-// protocol directly; it is used when BookmarkButton controllers talk
-// to each other.
-//
-// Other than the top level owner (the bookmark bar), all bookmark
-// button controllers have a parent controller.
-@protocol BookmarkButtonControllerProtocol
-
-// Close all bookmark folders, walking up the ownership chain.
-- (void)closeAllBookmarkFolders;
-
-// Close just my bookmark folder.
-- (void)closeBookmarkFolder:(id)sender;
-
-// Return the bookmark model for this controller.
-- (BookmarkModel*)bookmarkModel;
-
-// Perform drag enter/exit operations, such as hover-open and hover-close.
-- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)info;
-- (void)draggingExited:(id<NSDraggingInfo>)info;
-
-// Returns YES if a drag operation should lock the fullscreen overlay bar
-// visibility before starting. For example, dragging a bookmark button should
-// not lock the overlay if the bookmark bar is currently showing in detached
-// mode on the NTP.
-- (BOOL)dragShouldLockBarVisibility;
-
-// Perform the actual DnD of a bookmark or bookmark button.
-
-// |point| is in the base coordinate system of the destination window;
-// |it comes from an id<NSDraggingInfo>. |copy| is YES if a copy is to be
-// made and inserted into the new location while leaving the bookmark in
-// the old location, otherwise move the bookmark by removing from its old
-// location and inserting into the new location.
-- (BOOL)dragButton:(BookmarkButton*)sourceButton
- to:(NSPoint)point
- copy:(BOOL)copy;
-
-// Determine if the pasteboard from |info| has dragging data containing
-// bookmark(s) and perform the drag and return YES, otherwise return NO.
-- (BOOL)dragBookmarkData:(id<NSDraggingInfo>)info;
-
-// Determine if the drag pasteboard has any drag data of type
-// kBookmarkDictionaryListPboardType and, if so, return those elements
-// otherwise return an empty vector.
-- (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData;
-
-// Return YES if we should show the drop indicator, else NO. In some
-// cases (e.g. hover open) we don't want to show the drop indicator.
-// |point| is in the base coordinate system of the destination window;
-// |it comes from an id<NSDraggingInfo>.
-- (BOOL)shouldShowIndicatorShownForPoint:(NSPoint)point;
-
-// The x or y coordinate of (the middle of) the indicator to draw for
-// a drag of the source button to the given point (given in window
-// coordinates).
-// |point| is in the base coordinate system of the destination window;
-// |it comes from an id<NSDraggingInfo>.
-// TODO(viettrungluu,jrg): instead of this, make buttons move around.
-// http://crbug.com/35968
-- (CGFloat)indicatorPosForDragToPoint:(NSPoint)point;
-
-// Return the theme provider associated with this browser window.
-- (ThemeProvider*)themeProvider;
-
-// Called just before a child folder puts itself on screen.
-- (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child;
-
-// Called just before a child folder closes.
-- (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child;
-
-// Return a controller's folder controller for a subfolder, or nil.
-- (BookmarkBarFolderController*)folderController;
-
-// Add a new folder controller as triggered by the given folder button.
-// If there is a current folder controller, close it.
-- (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton;
-
-// Open all of the nodes for the given node with disposition.
-- (void)openAll:(const BookmarkNode*)node
- disposition:(WindowOpenDisposition)disposition;
-
-// There are several operations which may affect the contents of a bookmark
-// button controller after it has been created, primary of which are
-// cut/paste/delete and drag/drop. Such changes may involve coordinating
-// the bookmark button contents of two controllers (such as when a bookmark is
-// dragged from one folder to another). The bookmark bar controller
-// coordinates in response to notifications propogated by the bookmark model
-// through BookmarkBarBridge calls. The following three functions are
-// implemented by the controllers and are dispatched by the bookmark bar
-// controller in response to notifications coming in from the BookmarkBarBridge.
-
-// Add a button for the given node to the bar or folder menu. This is safe
-// to call when a folder menu window is open as that window will be updated.
-// And index of -1 means to append to the end (bottom).
-- (void)addButtonForNode:(const BookmarkNode*)node
- atIndex:(NSInteger)buttonIndex;
-
-// Given a list or |urls| and |titles|, create new bookmark nodes and add
-// them to the bookmark model such that they will be 1) added to the folder
-// represented by the button at |point| if it is a folder, or 2) inserted
-// into the parent of the non-folder bookmark at |point| in front of that
-// button. Returns YES if at least one bookmark was added.
-// TODO(mrossetti): Change function to use a pair-like structure for
-// URLs and titles. http://crbug.com/44411
-- (BOOL)addURLs:(NSArray*)urls withTitles:(NSArray*)titles at:(NSPoint)point;
-
-// Move a button from one place in the menu to another. This is safe
-// to call when a folder menu window is open as that window will be updated.
-- (void)moveButtonFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex;
-
-// Remove the bookmark button at the given index. Show the poof animation
-// if |animate:| is YES. It may be obvious, but this is safe
-// to call when a folder menu window is open as that window will be updated.
-- (void)removeButton:(NSInteger)buttonIndex animate:(BOOL)poof;
-
-// Determine the controller containing the button representing |node|, if any.
-- (id<BookmarkButtonControllerProtocol>)controllerForNode:
- (const BookmarkNode*)node;
-
-@end // @protocol BookmarkButtonControllerProtocol
-
-
-// Class for bookmark bar buttons that can be drag sources.
-@interface BookmarkButton : DraggableButton {
- @private
- IBOutlet NSObject<BookmarkButtonDelegate>* delegate_; // Weak.
-
- // Saved pointer to the BWC for the browser window that contains this button.
- // Used to lock and release bar visibility during a drag. The pointer is
- // saved because the bookmark button is no longer a part of a window at the
- // end of a drag operation (or, in fact, can be dragged to a completely
- // different window), so there is no way to retrieve the same BWC object after
- // a drag.
- BrowserWindowController* visibilityDelegate_; // weak
-
- NSPoint dragMouseOffset_;
- NSPoint dragEndScreenLocation_;
- BOOL dragPending_;
-}
-
-@property(assign, nonatomic) NSObject<BookmarkButtonDelegate>* delegate;
-
-// Return the bookmark node associated with this button, or NULL.
-- (const BookmarkNode*)bookmarkNode;
-
-// Return YES if this is a folder button (the node has subnodes).
-- (BOOL)isFolder;
-
-// At this time we represent an empty folder (e.g. the string
-// '(empty)') as a disabled button with no associated node.
-//
-// TODO(jrg): improve; things work but are slightly ugly since "empty"
-// and "one disabled button" are not the same thing.
-// http://crbug.com/35967
-- (BOOL)isEmpty;
-
-// Turn on or off pulsing of a bookmark button.
-// Triggered by the bookmark bubble.
-- (void)setIsContinuousPulsing:(BOOL)flag;
-
-// Return continuous pulse state.
-- (BOOL)isContinuousPulsing;
-
-// Return the location in screen coordinates where the remove animation should
-// be displayed.
-- (NSPoint)screenLocationForRemoveAnimation;
-
-@end // @interface BookmarkButton
-
-
-@interface BookmarkButton(TestingAPI)
-- (void)beginDrag:(NSEvent*)event;
-@end
-
-namespace bookmark_button {
-
-// Notifications for pulsing of bookmarks.
-extern NSString* const kPulseBookmarkButtonNotification;
-
-// Key for userInfo dict of a kPulseBookmarkButtonNotification.
-// Value is a [NSValue valueWithPointer:]; pointer is a (const BookmarkNode*).
-extern NSString* const kBookmarkKey;
-
-// Key for userInfo dict of a kPulseBookmarkButtonNotification.
-// Value is a [NSNumber numberWithBool:] to turn pulsing on or off.
-extern NSString* const kBookmarkPulseFlagKey;
-
-};
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button.mm b/chrome/browser/cocoa/bookmarks/bookmark_button.mm
deleted file mode 100644
index 9728e67..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button.mm
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-
-#include "base/logging.h"
-#import "base/scoped_nsobject.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/view_id_util.h"
-#include "chrome/browser/metrics/user_metrics.h"
-
-// The opacity of the bookmark button drag image.
-static const CGFloat kDragImageOpacity = 0.7;
-
-
-namespace bookmark_button {
-
-NSString* const kPulseBookmarkButtonNotification =
- @"PulseBookmarkButtonNotification";
-NSString* const kBookmarkKey = @"BookmarkKey";
-NSString* const kBookmarkPulseFlagKey = @"BookmarkPulseFlagKey";
-
-};
-
-@interface BookmarkButton(Private)
-
-// Make a drag image for the button.
-- (NSImage*)dragImage;
-
-@end // @interface BookmarkButton(Private)
-
-
-@implementation BookmarkButton
-
-@synthesize delegate = delegate_;
-
-- (id)initWithFrame:(NSRect)frameRect {
- // BookmarkButton's ViewID may be changed to VIEW_ID_OTHER_BOOKMARKS in
- // BookmarkBarController, so we can't just override -viewID method to return
- // it.
- if ((self = [super initWithFrame:frameRect]))
- view_id_util::SetID(self, VIEW_ID_BOOKMARK_BAR_ELEMENT);
- return self;
-}
-
-- (void)dealloc {
- if ([[self cell] respondsToSelector:@selector(safelyStopPulsing)])
- [[self cell] safelyStopPulsing];
- view_id_util::UnsetID(self);
- [super dealloc];
-}
-
-- (const BookmarkNode*)bookmarkNode {
- return [[self cell] bookmarkNode];
-}
-
-- (BOOL)isFolder {
- const BookmarkNode* node = [self bookmarkNode];
- return (node && node->is_folder());
-}
-
-- (BOOL)isEmpty {
- return [self bookmarkNode] ? NO : YES;
-}
-
-- (void)setIsContinuousPulsing:(BOOL)flag {
- [[self cell] setIsContinuousPulsing:flag];
-}
-
-- (BOOL)isContinuousPulsing {
- return [[self cell] isContinuousPulsing];
-}
-
-- (NSPoint)screenLocationForRemoveAnimation {
- NSPoint point;
-
- if (dragPending_) {
- // Use the position of the mouse in the drag image as the location.
- point = dragEndScreenLocation_;
- point.x += dragMouseOffset_.x;
- if ([self isFlipped]) {
- point.y += [self bounds].size.height - dragMouseOffset_.y;
- } else {
- point.y += dragMouseOffset_.y;
- }
- } else {
- // Use the middle of this button as the location.
- NSRect bounds = [self bounds];
- point = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
- point = [self convertPoint:point toView:nil];
- point = [[self window] convertBaseToScreen:point];
- }
-
- return point;
-}
-
-// By default, NSButton ignores middle-clicks.
-// But we want them.
-- (void)otherMouseUp:(NSEvent*)event {
- [self performClick:self];
-}
-
-// Overridden from DraggableButton.
-- (void)beginDrag:(NSEvent*)event {
- // Don't allow a drag of the empty node.
- // The empty node is a placeholder for "(empty)", to be revisited.
- if ([self isEmpty])
- return;
-
- if (![self delegate]) {
- NOTREACHED();
- return;
- }
- // Ask our delegate to fill the pasteboard for us.
- NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- [[self delegate] fillPasteboard:pboard forDragOfButton:self];
-
- // At the moment, moving bookmarks causes their buttons (like me!)
- // to be destroyed and rebuilt. Make sure we don't go away while on
- // the stack.
- [self retain];
-
- // Lock bar visibility, forcing the overlay to stay visible if we are in
- // fullscreen mode.
- if ([[self delegate] dragShouldLockBarVisibility]) {
- DCHECK(!visibilityDelegate_);
- NSWindow* window = [[self delegate] browserWindow];
- visibilityDelegate_ =
- [BrowserWindowController browserWindowControllerForWindow:window];
- [visibilityDelegate_ lockBarVisibilityForOwner:self
- withAnimation:NO
- delay:NO];
- }
- const BookmarkNode* node = [self bookmarkNode];
- const BookmarkNode* parent = node ? node->GetParent() : NULL;
- if (parent && parent->type() == BookmarkNode::FOLDER) {
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBarFolder_DragStart"));
- } else {
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_DragStart"));
- }
-
- dragMouseOffset_ = [self convertPointFromBase:[event locationInWindow]];
- dragPending_ = YES;
-
- CGFloat yAt = [self bounds].size.height;
- NSSize dragOffset = NSMakeSize(0.0, 0.0);
- [self dragImage:[self dragImage] at:NSMakePoint(0, yAt) offset:dragOffset
- event:event pasteboard:pboard source:self slideBack:YES];
-
- // And we're done.
- dragPending_ = NO;
- [self autorelease];
-}
-
-// Overridden to release bar visibility.
-- (void)endDrag {
- // visibilityDelegate_ can be nil if we're detached, and that's fine.
- [visibilityDelegate_ releaseBarVisibilityForOwner:self
- withAnimation:YES
- delay:YES];
- visibilityDelegate_ = nil;
- [super endDrag];
-}
-
-- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
- NSDragOperation operation = NSDragOperationCopy;
- if (isLocal) {
- operation |= NSDragOperationMove;
- }
- if ([delegate_ canDragBookmarkButtonToTrash:self]) {
- operation |= NSDragOperationDelete;
- }
- return operation;
-}
-
-- (void)draggedImage:(NSImage *)anImage
- endedAt:(NSPoint)aPoint
- operation:(NSDragOperation)operation {
- if (operation & NSDragOperationDelete) {
- dragEndScreenLocation_ = aPoint;
- [delegate_ didDragBookmarkToTrash:self];
- }
-}
-
-// mouseEntered: and mouseExited: are called from our
-// BookmarkButtonCell. We redirect this information to our delegate.
-// The controller can then perform menu-like actions (e.g. "hover over
-// to open menu").
-- (void)mouseEntered:(NSEvent*)event {
- [delegate_ mouseEnteredButton:self event:event];
-}
-
-// See comments above mouseEntered:.
-- (void)mouseExited:(NSEvent*)event {
- [delegate_ mouseExitedButton:self event:event];
-}
-
-@end
-
-@implementation BookmarkButton(Private)
-
-- (NSImage*)dragImage {
- NSRect bounds = [self bounds];
-
- // Grab the image from the screen and put it in an |NSImage|. We can't use
- // this directly since we need to clip it and set its opacity. This won't work
- // if the source view is clipped. Fortunately, we don't display clipped
- // bookmark buttons.
- [self lockFocus];
- scoped_nsobject<NSBitmapImageRep>
- bitmap([[NSBitmapImageRep alloc] initWithFocusedViewRect:bounds]);
- [self unlockFocus];
- scoped_nsobject<NSImage> image([[NSImage alloc] initWithSize:[bitmap size]]);
- [image addRepresentation:bitmap];
-
- // Make an autoreleased |NSImage|, which will be returned, and draw into it.
- // By default, the |NSImage| will be completely transparent.
- NSImage* dragImage =
- [[[NSImage alloc] initWithSize:[bitmap size]] autorelease];
- [dragImage lockFocus];
-
- // Draw the image with the appropriate opacity, clipping it tightly.
- GradientButtonCell* cell = static_cast<GradientButtonCell*>([self cell]);
- DCHECK([cell isKindOfClass:[GradientButtonCell class]]);
- [[cell clipPathForFrame:bounds inView:self] setClip];
- [image drawAtPoint:NSMakePoint(0, 0)
- fromRect:NSMakeRect(0, 0, NSWidth(bounds), NSHeight(bounds))
- operation:NSCompositeSourceOver
- fraction:kDragImageOpacity];
-
- [dragImage unlockFocus];
- return dragImage;
-}
-
-@end // @implementation BookmarkButton(Private)
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button_cell.h b/chrome/browser/cocoa/bookmarks/bookmark_button_cell.h
deleted file mode 100644
index 45d83e3..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button_cell.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_BUTTON_CELL_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BUTTON_CELL_H_
-#pragma once
-
-#import "base/cocoa_protocols_mac.h"
-#import "chrome/browser/cocoa/gradient_button_cell.h"
-
-class BookmarkNode;
-
-// A button cell that handles drawing/highlighting of buttons in the
-// bookmark bar. This cell forwards mouseEntered/mouseExited events
-// to its control view so that pseudo-menu operations
-// (e.g. hover-over to open) can be implemented.
-@interface BookmarkButtonCell : GradientButtonCell<NSMenuDelegate> {
- @private
- BOOL empty_; // is this an "empty" button placeholder button cell?
-
- // Starting index of bookmarkFolder children that we care to use.
- int startingChildIndex_;
-
- // Should we draw the folder arrow as needed? Not used for the bar
- // itself but used on the folder windows.
- BOOL drawFolderArrow_;
-
- // Arrow for folders
- scoped_nsobject<NSImage> arrowImage_;
-}
-
-@property (nonatomic, readwrite, assign) const BookmarkNode* bookmarkNode;
-@property (nonatomic, readwrite, assign) int startingChildIndex;
-@property (nonatomic, readwrite, assign) BOOL drawFolderArrow;
-
-// Create a button cell which draws with a theme.
-+ (id)buttonCellForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage;
-
-// Initialize a button cell which draws with a theme.
-// Designated initializer.
-- (id)initForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage;
-
-- (BOOL)empty; // returns YES if empty.
-- (void)setEmpty:(BOOL)empty;
-
-// |-setBookmarkCellText:image:| is used to set the text and image of
-// a BookmarkButtonCell, and align the image to the left (NSImageLeft)
-// if there is text in the title, and centered (NSImageCenter) if
-// there is not. If |title| is nil, do not reset the title.
-- (void)setBookmarkCellText:(NSString*)title
- image:(NSImage*)image;
-
-// Set the color of text in this cell.
-- (void)setTextColor:(NSColor*)color;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_BUTTON_CELL_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/cocoa/bookmarks/bookmark_button_cell.mm
deleted file mode 100644
index 8cb59e9..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button_cell.mm
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-
-#include "app/l10n_util_mac.h"
-#include "base/logging.h"
-#include "base/nsimage_cache_mac.h"
-#include "base/sys_string_conversions.h"
-#import "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/image_utils.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "grit/generated_resources.h"
-
-
-@interface BookmarkButtonCell(Private)
-- (void)configureBookmarkButtonCell;
-@end
-
-
-@implementation BookmarkButtonCell
-
-@synthesize startingChildIndex = startingChildIndex_;
-@synthesize drawFolderArrow = drawFolderArrow_;
-
-+ (id)buttonCellForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage {
- id buttonCell =
- [[[BookmarkButtonCell alloc] initForNode:node
- contextMenu:contextMenu
- cellText:cellText
- cellImage:cellImage]
- autorelease];
- return buttonCell;
-}
-
-- (id)initForNode:(const BookmarkNode*)node
- contextMenu:(NSMenu*)contextMenu
- cellText:(NSString*)cellText
- cellImage:(NSImage*)cellImage {
- if ((self = [super initTextCell:cellText])) {
- [self configureBookmarkButtonCell];
-
- [self setBookmarkNode:node];
-
- if (node) {
- NSString* title = base::SysUTF16ToNSString(node->GetTitle());
- [self setBookmarkCellText:title image:cellImage];
- [self setMenu:contextMenu];
- } else {
- [self setEmpty:YES];
- [self setBookmarkCellText:l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU)
- image:nil];
- }
- }
-
- return self;
-}
-
-- (id)initTextCell:(NSString*)string {
- return [self initForNode:nil contextMenu:nil cellText:string cellImage:nil];
-}
-
-// Used by the off-the-side menu, the only case where a
-// BookmarkButtonCell is loaded from a nib.
-- (void)awakeFromNib {
- [self configureBookmarkButtonCell];
-}
-
-// Perform all normal init routines specific to the BookmarkButtonCell.
-- (void)configureBookmarkButtonCell {
- [self setButtonType:NSMomentaryPushInButton];
- [self setBezelStyle:NSShadowlessSquareBezelStyle];
- [self setShowsBorderOnlyWhileMouseInside:YES];
- [self setControlSize:NSSmallControlSize];
- [self setAlignment:NSLeftTextAlignment];
- [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
- [self setWraps:NO];
- // NSLineBreakByTruncatingMiddle seems more common on OSX but let's
- // try to match Windows for a bit to see what happens.
- [self setLineBreakMode:NSLineBreakByTruncatingTail];
-
- // Theming doesn't work for bookmark buttons yet (cell text is chucked).
- [super setShouldTheme:NO];
-}
-
-- (BOOL)empty {
- return empty_;
-}
-
-- (void)setEmpty:(BOOL)empty {
- empty_ = empty;
- [self setShowsBorderOnlyWhileMouseInside:!empty];
-}
-
-- (NSSize)cellSizeForBounds:(NSRect)aRect {
- NSSize size = [super cellSizeForBounds:aRect];
- // Cocoa seems to slightly underestimate how much space we need, so we
- // compensate here to avoid a clipped rendering.
- size.width += 2;
- size.height += 4;
- return size;
-}
-
-- (void)setBookmarkCellText:(NSString*)title
- image:(NSImage*)image {
- title = [title stringByReplacingOccurrencesOfString:@"\n"
- withString:@" "];
- title = [title stringByReplacingOccurrencesOfString:@"\r"
- withString:@" "];
- // If there is no title, squeeze things tight by displaying only the image; by
- // default, Cocoa leaves extra space in an attempt to display an empty title.
- if ([title length]) {
- [self setImagePosition:NSImageLeft];
- [self setTitle:title];
- } else {
- [self setImagePosition:NSImageOnly];
- }
-
- if (image)
- [self setImage:image];
-}
-
-- (void)setBookmarkNode:(const BookmarkNode*)node {
- [self setRepresentedObject:[NSValue valueWithPointer:node]];
-}
-
-- (const BookmarkNode*)bookmarkNode {
- return static_cast<const BookmarkNode*>([[self representedObject]
- pointerValue]);
-}
-
-// We share the context menu among all bookmark buttons. To allow us
-// to disambiguate when needed (e.g. "open bookmark"), we set the
-// menu's associated bookmark node ID to be our represented object.
-- (NSMenu*)menu {
- if (empty_)
- return nil;
- BookmarkMenu* menu = (BookmarkMenu*)[super menu];
- const BookmarkNode* node =
- static_cast<const BookmarkNode*>([[self representedObject] pointerValue]);
-
- if (node->GetParent() && node->GetParent()->type() == BookmarkNode::FOLDER) {
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBarFolder_CtxMenu"));
- } else {
- UserMetrics::RecordAction(UserMetricsAction("BookmarkBar_CtxMenu"));
- }
-
- [menu setRepresentedObject:[NSNumber numberWithLongLong:node->id()]];
-
- return menu;
-}
-
-// Unfortunately, NSCell doesn't already have something like this.
-// TODO(jrg): consider placing in GTM.
-- (void)setTextColor:(NSColor*)color {
-
- // We can't properly set the cell's text color without a control.
- // In theory we could just save the next for later and wait until
- // the cell is moved to a control, but there is no obvious way to
- // accomplish that (e.g. no "cellDidMoveToControl" notification.)
- DCHECK([self controlView]);
-
- scoped_nsobject<NSMutableParagraphStyle> style([NSMutableParagraphStyle new]);
- [style setAlignment:NSLeftTextAlignment];
- NSDictionary* dict = [NSDictionary
- dictionaryWithObjectsAndKeys:color,
- NSForegroundColorAttributeName,
- [self font], NSFontAttributeName,
- style.get(), NSParagraphStyleAttributeName,
- nil];
- scoped_nsobject<NSAttributedString> ats([[NSAttributedString alloc]
- initWithString:[self title]
- attributes:dict]);
- NSButton* button = static_cast<NSButton*>([self controlView]);
- if (button) {
- DCHECK([button isKindOfClass:[NSButton class]]);
- [button setAttributedTitle:ats.get()];
- }
-}
-
-// To implement "hover open a bookmark button to open the folder"
-// which feels like menus, we override NSButtonCell's mouseEntered:
-// and mouseExited:, then and pass them along to our owning control.
-// Note: as verified in a debugger, mouseEntered: does NOT increase
-// the retainCount of the cell or its owning control.
-- (void)mouseEntered:(NSEvent*)event {
- [super mouseEntered:event];
- [[self controlView] mouseEntered:event];
-}
-
-// See comment above mouseEntered:, above.
-- (void)mouseExited:(NSEvent*)event {
- [[self controlView] mouseExited:event];
- [super mouseExited:event];
-}
-
-- (void)setDrawFolderArrow:(BOOL)draw {
- drawFolderArrow_ = draw;
- if (draw && !arrowImage_) {
- arrowImage_.reset([nsimage_cache::ImageNamed(@"menu_hierarchy_arrow.pdf")
- retain]);
- }
-}
-
-// Add extra size for the arrow so it doesn't overlap the text.
-// Does not sanity check to be sure this is actually a folder node.
-- (NSSize)cellSize {
- NSSize cellSize = [super cellSize];
- if (drawFolderArrow_) {
- cellSize.width += [arrowImage_ size].width; // plus margin?
- }
- return cellSize;
-}
-
-// Override cell drawing to add a submenu arrow like a real menu.
-- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
- // First draw "everything else".
- [super drawInteriorWithFrame:cellFrame inView:controlView];
-
- // If asked to do so, and if a folder, draw the arrow.
- if (!drawFolderArrow_)
- return;
- BookmarkButton* button = static_cast<BookmarkButton*>([self controlView]);
- DCHECK([button respondsToSelector:@selector(isFolder)]);
- if ([button isFolder]) {
- NSRect imageRect = NSZeroRect;
- imageRect.size = [arrowImage_ size];
- NSRect drawRect = NSOffsetRect(imageRect,
- NSWidth(cellFrame) - NSWidth(imageRect),
- (NSHeight(cellFrame) / 2.0) -
- (NSHeight(imageRect) / 2.0));
- [arrowImage_ drawInRect:drawRect
- fromRect:imageRect
- operation:NSCompositeSourceOver
- fraction:[self isEnabled] ? 1.0 : 0.5
- neverFlipped:YES];
- }
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button_cell_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_button_cell_unittest.mm
deleted file mode 100644
index 1c4e89f..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button_cell_unittest.mm
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "app/resource_bundle.h"
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "grit/app_resources.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-// Simple class to remember how many mouseEntered: and mouseExited:
-// calls it gets. Only used by BookmarkMouseForwarding but placed
-// at the top of the file to keep it outside the anon namespace.
-@interface ButtonRemembersMouseEnterExit : NSButton {
- @public
- int enters_;
- int exits_;
-}
-@end
-
-@implementation ButtonRemembersMouseEnterExit
-- (void)mouseEntered:(NSEvent*)event {
- enters_++;
-}
-- (void)mouseExited:(NSEvent*)event {
- exits_++;
-}
-@end
-
-
-namespace {
-
-class BookmarkButtonCellTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
-};
-
-// Make sure it's not totally bogus
-TEST_F(BookmarkButtonCellTest, SizeForBounds) {
- NSRect frame = NSMakeRect(0, 0, 50, 30);
- scoped_nsobject<NSButton> view([[NSButton alloc] initWithFrame:frame]);
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initTextCell:@"Testing"]);
- [view setCell:cell.get()];
- [[test_window() contentView] addSubview:view];
-
- NSRect r = NSMakeRect(0, 0, 100, 100);
- NSSize size = [cell.get() cellSizeForBounds:r];
- EXPECT_TRUE(size.width > 0 && size.height > 0);
- EXPECT_TRUE(size.width < 200 && size.height < 200);
-}
-
-// Make sure icon-only buttons are squeezed tightly.
-TEST_F(BookmarkButtonCellTest, IconOnlySqueeze) {
- NSRect frame = NSMakeRect(0, 0, 50, 30);
- scoped_nsobject<NSButton> view([[NSButton alloc] initWithFrame:frame]);
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initTextCell:@"Testing"]);
- [view setCell:cell.get()];
- [[test_window() contentView] addSubview:view];
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- scoped_nsobject<NSImage> image([rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON)
- retain]);
- EXPECT_TRUE(image.get());
-
- NSRect r = NSMakeRect(0, 0, 100, 100);
- [cell setBookmarkCellText:@" " image:image];
- CGFloat two_space_width = [cell.get() cellSizeForBounds:r].width;
- [cell setBookmarkCellText:@" " image:image];
- CGFloat one_space_width = [cell.get() cellSizeForBounds:r].width;
- [cell setBookmarkCellText:@"" image:image];
- CGFloat zero_space_width = [cell.get() cellSizeForBounds:r].width;
-
- // Make sure the switch to "no title" is more significant than we
- // would otherwise see by decreasing the length of the title.
- CGFloat delta1 = two_space_width - one_space_width;
- CGFloat delta2 = one_space_width - zero_space_width;
- EXPECT_GT(delta2, delta1);
-
-}
-
-// Make sure the default from the base class is overridden.
-TEST_F(BookmarkButtonCellTest, MouseEnterStuff) {
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initTextCell:@"Testing"]);
- // Setting the menu should have no affect since we either share or
- // dynamically compose the menu given a node.
- [cell setMenu:[[[BookmarkMenu alloc] initWithTitle:@"foo"] autorelease]];
- EXPECT_FALSE([cell menu]);
-
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* node = model->GetBookmarkBarNode();
- [cell setEmpty:NO];
- [cell setBookmarkNode:node];
- EXPECT_TRUE([cell showsBorderOnlyWhileMouseInside]);
- EXPECT_TRUE([cell menu]);
-
- [cell setEmpty:YES];
- EXPECT_FALSE([cell.get() showsBorderOnlyWhileMouseInside]);
- EXPECT_FALSE([cell menu]);
-}
-
-TEST_F(BookmarkButtonCellTest, BookmarkNode) {
- BookmarkModel& model(*(helper_.profile()->GetBookmarkModel()));
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initTextCell:@"Testing"]);
-
- const BookmarkNode* node = model.GetBookmarkBarNode();
- [cell setBookmarkNode:node];
- EXPECT_EQ(node, [cell bookmarkNode]);
-
- node = model.other_node();
- [cell setBookmarkNode:node];
- EXPECT_EQ(node, [cell bookmarkNode]);
-}
-
-TEST_F(BookmarkButtonCellTest, BookmarkMouseForwarding) {
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initTextCell:@"Testing"]);
- scoped_nsobject<ButtonRemembersMouseEnterExit>
- button([[ButtonRemembersMouseEnterExit alloc]
- initWithFrame:NSMakeRect(0,0,50,50)]);
- [button setCell:cell.get()];
- EXPECT_EQ(0, button.get()->enters_);
- EXPECT_EQ(0, button.get()->exits_);
- NSEvent* event = [NSEvent mouseEventWithType:NSMouseMoved
- location:NSMakePoint(10,10)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- eventNumber:0
- clickCount:0
- pressure:0];
- [cell mouseEntered:event];
- EXPECT_TRUE(button.get()->enters_ && !button.get()->exits_);
-
- for (int i = 0; i < 3; i++)
- [cell mouseExited:event];
- EXPECT_EQ(button.get()->enters_, 1);
- EXPECT_EQ(button.get()->exits_, 3);
-}
-
-// Confirms a cell created in a nib is initialized properly
-TEST_F(BookmarkButtonCellTest, Awake) {
- scoped_nsobject<BookmarkButtonCell> cell([[BookmarkButtonCell alloc] init]);
- [cell awakeFromNib];
- EXPECT_EQ(NSLeftTextAlignment, [cell alignment]);
-}
-
-// Subfolder arrow details.
-TEST_F(BookmarkButtonCellTest, FolderArrow) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* bar = model->GetBookmarkBarNode();
- const BookmarkNode* node = model->AddURL(bar, bar->GetChildCount(),
- ASCIIToUTF16("title"),
- GURL("http://www.google.com"));
- scoped_nsobject<BookmarkButtonCell> cell(
- [[BookmarkButtonCell alloc] initForNode:node
- contextMenu:nil
- cellText:@"small"
- cellImage:nil]);
- EXPECT_TRUE(cell.get());
-
- NSSize size = [cell cellSize];
- // sanity check
- EXPECT_GE(size.width, 2);
- EXPECT_GE(size.height, 2);
-
- // Once we turn on arrow drawing make sure there is now room for it.
- [cell setDrawFolderArrow:YES];
- NSSize arrowSize = [cell cellSize];
- EXPECT_GT(arrowSize.width, size.width);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_button_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_button_unittest.mm
deleted file mode 100644
index ed8964a..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_button_unittest.mm
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button_cell.h"
-#import "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#import "chrome/browser/cocoa/test_event_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-// Fake BookmarkButton delegate to get a pong on mouse entered/exited
-@interface FakeButtonDelegate : NSObject<BookmarkButtonDelegate> {
- @public
- int entered_;
- int exited_;
- BOOL canDragToTrash_;
- int didDragToTrashCount_;
-}
-@end
-
-@implementation FakeButtonDelegate
-
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button {
-}
-
-- (void)mouseEnteredButton:(id)buton event:(NSEvent*)event {
- entered_++;
-}
-
-- (void)mouseExitedButton:(id)buton event:(NSEvent*)event {
- exited_++;
-}
-
-- (BOOL)dragShouldLockBarVisibility {
- return NO;
-}
-
-- (NSWindow*)browserWindow {
- return nil;
-}
-
-- (BOOL)canDragBookmarkButtonToTrash:(BookmarkButton*)button {
- return canDragToTrash_;
-}
-
-- (void)didDragBookmarkToTrash:(BookmarkButton*)button {
- didDragToTrashCount_++;
-}
-
-@end
-
-namespace {
-
-class BookmarkButtonTest : public CocoaTest {
-};
-
-// Make sure nothing leaks
-TEST_F(BookmarkButtonTest, Create) {
- scoped_nsobject<BookmarkButton> button;
- button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
-}
-
-// Test folder and empty node queries.
-TEST_F(BookmarkButtonTest, FolderAndEmptyOrNot) {
- BrowserTestHelper helper_;
- scoped_nsobject<BookmarkButton> button;
- scoped_nsobject<BookmarkButtonCell> cell;
-
- button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
- cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
- [button setCell:cell];
-
- EXPECT_TRUE([button isEmpty]);
- EXPECT_FALSE([button isFolder]);
- EXPECT_FALSE([button bookmarkNode]);
-
- NSEvent* downEvent =
- test_event_utils::LeftMouseDownAtPoint(NSMakePoint(10,10));
- // Since this returns (does not actually begin a modal drag), success!
- [button beginDrag:downEvent];
-
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* node = model->GetBookmarkBarNode();
- [cell setBookmarkNode:node];
- EXPECT_FALSE([button isEmpty]);
- EXPECT_TRUE([button isFolder]);
- EXPECT_EQ([button bookmarkNode], node);
-
- node = model->AddURL(node, 0, ASCIIToUTF16("hi mom"),
- GURL("http://www.google.com"));
- [cell setBookmarkNode:node];
- EXPECT_FALSE([button isEmpty]);
- EXPECT_FALSE([button isFolder]);
- EXPECT_EQ([button bookmarkNode], node);
-}
-
-TEST_F(BookmarkButtonTest, MouseEnterExitRedirect) {
- NSEvent* moveEvent =
- test_event_utils::MouseEventAtPoint(NSMakePoint(10,10), NSMouseMoved, 0);
- scoped_nsobject<BookmarkButton> button;
- scoped_nsobject<BookmarkButtonCell> cell;
- scoped_nsobject<FakeButtonDelegate>
- delegate([[FakeButtonDelegate alloc] init]);
- button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
- cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
- [button setCell:cell];
- [button setDelegate:delegate];
-
- EXPECT_EQ(0, delegate.get()->entered_);
- EXPECT_EQ(0, delegate.get()->exited_);
-
- [button mouseEntered:moveEvent];
- EXPECT_EQ(1, delegate.get()->entered_);
- EXPECT_EQ(0, delegate.get()->exited_);
-
- [button mouseExited:moveEvent];
- [button mouseExited:moveEvent];
- EXPECT_EQ(1, delegate.get()->entered_);
- EXPECT_EQ(2, delegate.get()->exited_);
-}
-
-TEST_F(BookmarkButtonTest, DragToTrash) {
- BrowserTestHelper helper_;
-
- scoped_nsobject<BookmarkButton> button;
- scoped_nsobject<BookmarkButtonCell> cell;
- scoped_nsobject<FakeButtonDelegate>
- delegate([[FakeButtonDelegate alloc] init]);
- button.reset([[BookmarkButton alloc] initWithFrame:NSMakeRect(0,0,500,500)]);
- cell.reset([[BookmarkButtonCell alloc] initTextCell:@"hi mom"]);
- [button setCell:cell];
- [button setDelegate:delegate];
-
- // Add a deletable bookmark to the button.
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* barNode = model->GetBookmarkBarNode();
- const BookmarkNode* node = model->AddURL(barNode, 0, ASCIIToUTF16("hi mom"),
- GURL("http://www.google.com"));
- [cell setBookmarkNode:node];
-
- // Verify that if canDragBookmarkButtonToTrash is NO then the button can't
- // be dragged to the trash.
- delegate.get()->canDragToTrash_ = NO;
- NSDragOperation operation = [button draggingSourceOperationMaskForLocal:NO];
- EXPECT_EQ(0u, operation & NSDragOperationDelete);
- operation = [button draggingSourceOperationMaskForLocal:YES];
- EXPECT_EQ(0u, operation & NSDragOperationDelete);
-
- // Verify that if canDragBookmarkButtonToTrash is YES then the button can
- // be dragged to the trash.
- delegate.get()->canDragToTrash_ = YES;
- operation = [button draggingSourceOperationMaskForLocal:NO];
- EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
- operation = [button draggingSourceOperationMaskForLocal:YES];
- EXPECT_EQ(NSDragOperationDelete, operation & NSDragOperationDelete);
-
- // Verify that canDragBookmarkButtonToTrash is called when expected.
- delegate.get()->canDragToTrash_ = YES;
- EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
- [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationCopy];
- EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
- [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationMove];
- EXPECT_EQ(0, delegate.get()->didDragToTrashCount_);
- [button draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationDelete];
- EXPECT_EQ(1, delegate.get()->didDragToTrashCount_);
-}
-
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_drag_source.h b/chrome/browser/cocoa/bookmarks/bookmark_drag_source.h
deleted file mode 100644
index 5c33797..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_drag_source.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "chrome/browser/bookmarks/bookmark_node_data.h"
-#include "chrome/browser/cocoa/web_contents_drag_source.h"
-
-// A class that handles tracking and event processing for a drag and drop
-// originating from the content area.
-@interface BookmarkDragSource : WebContentsDragSource {
- @private
- // Our drop data. Should only be initialized once.
- std::vector<BookmarkNodeData::Element> dropData_;
-
- Profile* profile_;
-}
-
-// Initialize a DragDataSource object for a drag (originating on the given
-// contentsView and with the given dropData and pboard). Fill the pasteboard
-// with data types appropriate for dropData.
-- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
- dropData:
- (const std::vector<BookmarkNodeData::Element>&)dropData
- profile:(Profile*)profile
- pasteboard:(NSPasteboard*)pboard
- dragOperationMask:(NSDragOperation)dragOperationMask;
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_drag_source.mm b/chrome/browser/cocoa/bookmarks/bookmark_drag_source.mm
deleted file mode 100644
index 64f9de2..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_drag_source.mm
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_drag_source.h"
-
-#include "chrome/browser/bookmarks/bookmark_pasteboard_helper_mac.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents/tab_contents_view_mac.h"
-
-@implementation BookmarkDragSource
-
-- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
- dropData:
- (const std::vector<BookmarkNodeData::Element>&)dropData
- profile:(Profile*)profile
- pasteboard:(NSPasteboard*)pboard
- dragOperationMask:(NSDragOperation)dragOperationMask {
- self = [super initWithContentsView:contentsView
- pasteboard:pboard
- dragOperationMask:dragOperationMask];
- if (self) {
- dropData_ = dropData;
- profile_ = profile;
- }
-
- return self;
-}
-
-- (void)fillPasteboard {
- bookmark_pasteboard_helper_mac::WriteToDragClipboard(dropData_,
- profile_->GetPath().value());
-}
-
-- (NSImage*)dragImage {
- // TODO(feldstein): Do something better than this. Should have badging
- // and a single drag image.
- // http://crbug.com/37264
- return [NSImage imageNamed:NSImageNameMultipleDocuments];
-}
-
-@end // @implementation BookmarkDragSource
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h
deleted file mode 100644
index 5880d79..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#import "base/cocoa_protocols_mac.h"
-#include "base/scoped_ptr.h"
-#include "base/scoped_nsobject.h"
-#include "chrome/browser/bookmarks/bookmark_editor.h"
-
-class BookmarkEditorBaseControllerBridge;
-class BookmarkModel;
-@class BookmarkTreeBrowserCell;
-
-// A base controller class for bookmark creation and editing dialogs which
-// present the current bookmark folder structure in a tree view. Do not
-// instantiate this controller directly -- use one of its derived classes.
-// NOTE: If a derived class is intended to be dispatched via the
-// BookmarkEditor::Show static function found in the accompanying
-// implementation, that function will need to be update.
-@interface BookmarkEditorBaseController : NSWindowController {
- @private
- IBOutlet NSButton* newFolderButton_;
- IBOutlet NSButton* okButton_; // Used for unit testing only.
- IBOutlet NSTreeController* folderTreeController_;
- IBOutlet NSOutlineView* folderTreeView_;
-
- NSWindow* parentWindow_; // weak
- Profile* profile_; // weak
- const BookmarkNode* parentNode_; // weak; owned by the model
- BookmarkEditor::Configuration configuration_;
- NSString* initialName_;
- NSString* displayName_; // Bound to a text field in the dialog.
- BOOL okEnabled_; // Bound to the OK button.
- // An array of BookmarkFolderInfo where each item describes a folder in the
- // BookmarkNode structure.
- scoped_nsobject<NSArray> folderTreeArray_;
- // Bound to the table view giving a path to the current selections, of which
- // there should only ever be one.
- scoped_nsobject<NSArray> tableSelectionPaths_;
- // C++ bridge object that observes the BookmarkModel for me.
- scoped_ptr<BookmarkEditorBaseControllerBridge> observer_;
-}
-
-@property (nonatomic, copy) NSString* initialName;
-@property (nonatomic, copy) NSString* displayName;
-@property (nonatomic, assign) BOOL okEnabled;
-@property (nonatomic, retain, readonly) NSArray* folderTreeArray;
-@property (nonatomic, copy) NSArray* tableSelectionPaths;
-
-// Designated initializer. Derived classes should call through to this init.
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- nibName:(NSString*)nibName
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- configuration:(BookmarkEditor::Configuration)configuration;
-
-// Run the bookmark editor as a modal sheet. Does not block.
-- (void)runAsModalSheet;
-
-// Create a new folder at the end of the selected parent folder, give it
-// an untitled name, and put it into editing mode.
-- (IBAction)newFolder:(id)sender;
-
-// The cancel action will dismiss the dialog. Derived classes which
-// override cancel:, must call this after accessing any dialog-related
-// data.
-- (IBAction)cancel:(id)sender;
-
-// The OK action will dismiss the dialog. This action is bound
-// to the OK button of a dialog which presents a tree view of a profile's
-// folder hierarchy and allows the creation of new folders within that tree.
-// When the OK button is pressed, this function will: 1) call the derived
-// class's -[willCommit] function, 2) create any new folders created by
-// the user while the dialog is presented, 3) call the derived class's
-// -[didCommit] function, and then 4) dismiss the dialog. At least one
-// of -[willCommit] and -[didCommit] must be provided by the derived class
-// and should return a NSNumber containing a BOOL or nil ('nil' means YES)
-// indicating if the operation should be allowed to continue.
-// Note: A derived class should not override the ok: action.
-- (IBAction)ok:(id)sender;
-
-// Methods for use by derived classes only.
-
-// Determine and returns the rightmost selected/highlighted element (node)
-// in the bookmark tree view if the tree view is showing, otherwise returns
-// the original |parentNode_|. If the tree view is showing but nothing is
-// selected then the root node is returned.
-- (const BookmarkNode*)selectedNode;
-
-// Select/highlight the given node within the browser tree view. If the
-// node is nil then select the bookmark bar node. Exposed for unit test.
-- (void)selectNodeInBrowser:(const BookmarkNode*)node;
-
-// Notifications called when the BookmarkModel changes out from under me.
-- (void)nodeRemoved:(const BookmarkNode*)node
- fromParent:(const BookmarkNode*)parent;
-- (void)modelChangedPreserveSelection:(BOOL)preserve;
-
-// Accessors
-- (BookmarkModel*)bookmarkModel;
-- (const BookmarkNode*)parentNode;
-
-@end
-
-// Describes the profile's bookmark folder structure: the folder name, the
-// original BookmarkNode pointer (if the folder already exists), a BOOL
-// indicating if the folder is new (meaning: created during this session
-// but not yet committed to the bookmark structure), and an NSArray of
-// child folder BookmarkFolderInfo's following this same structure.
-@interface BookmarkFolderInfo : NSObject {
- @private
- NSString* folderName_;
- const BookmarkNode* folderNode_; // weak
- NSMutableArray* children_;
- BOOL newFolder_;
-}
-
-@property (nonatomic, copy) NSString* folderName;
-@property (nonatomic, assign) const BookmarkNode* folderNode;
-@property (nonatomic, retain) NSMutableArray* children;
-@property (nonatomic, assign) BOOL newFolder;
-
-// Convenience creator for adding a new folder to the editor's bookmark
-// structure. This folder will be added to the bookmark model when the
-// user accepts the dialog. |folderName| must be provided.
-+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName;
-
-// Designated initializer. |folderName| must be provided. For folders which
-// already exist in the bookmark model, |folderNode| and |children| (if any
-// children are already attached to this folder) must be provided and
-// |newFolder| should be NO. For folders which the user has added during
-// this session and which have not been committed yet, |newFolder| should be
-// YES and |folderNode| and |children| should be NULL/nil.
-- (id)initWithFolderName:(NSString*)folderName
- folderNode:(const BookmarkNode*)folderNode
- children:(NSMutableArray*)children
- newFolder:(BOOL)newFolder;
-
-// Convenience creator used during construction of the editor's bookmark
-// structure. |folderName| and |folderNode| must be provided. |children|
-// is optional. Private: exposed here for unit testing purposes.
-+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName
- folderNode:(const BookmarkNode*)folderNode
- children:(NSMutableArray*)children;
-
-@end
-
-@interface BookmarkEditorBaseController(TestingAPI)
-
-@property (nonatomic, readonly) BOOL okButtonEnabled;
-
-// Create any newly added folders. New folders are nodes in folderTreeArray
-// which are marked as being new (i.e. their kFolderTreeNewFolderKey
-// dictionary item is YES). This is called by -[ok:].
-- (void)createNewFolders;
-
-// Select the given bookmark node within the tree view.
-- (void)selectTestNodeInBrowser:(const BookmarkNode*)node;
-
-// Return the dictionary for the folder selected in the tree.
-- (BookmarkFolderInfo*)selectedFolder;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_EDITOR_BASE_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.mm
deleted file mode 100644
index 1f0274e..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.mm
+++ /dev/null
@@ -1,604 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include <stack>
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h"
-
-#include "app/l10n_util.h"
-#include "app/l10n_util_mac.h"
-#include "base/logging.h"
-#include "base/mac_util.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_all_tabs_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#include "chrome/browser/profile.h"
-#include "grit/generated_resources.h"
-
-@interface BookmarkEditorBaseController ()
-
-// Return the folder tree object for the given path.
-- (BookmarkFolderInfo*)folderForIndexPath:(NSIndexPath*)path;
-
-// (Re)build the folder tree from the BookmarkModel's current state.
-- (void)buildFolderTree;
-
-// Notifies the controller that the bookmark model has changed.
-// |selection| specifies if the current selection should be
-// maintained (usually YES).
-- (void)modelChangedPreserveSelection:(BOOL)preserve;
-
-// Notifies the controller that a node has been removed.
-- (void)nodeRemoved:(const BookmarkNode*)node
- fromParent:(const BookmarkNode*)parent;
-
-// Given a folder node, collect an array containing BookmarkFolderInfos
-// describing its subchildren which are also folders.
-- (NSMutableArray*)addChildFoldersFromNode:(const BookmarkNode*)node;
-
-// Scan the folder tree stemming from the given tree folder and create
-// any newly added folders. Pass down info for the folder which was
-// selected before we began creating folders.
-- (void)createNewFoldersForFolder:(BookmarkFolderInfo*)treeFolder
- selectedFolderInfo:(BookmarkFolderInfo*)selectedFolderInfo;
-
-// Scan the folder tree looking for the given bookmark node and return
-// the selection path thereto.
-- (NSIndexPath*)selectionPathForNode:(const BookmarkNode*)node;
-
-@end
-
-// static; implemented for each platform. Update this function for new
-// classes derived from BookmarkEditorBaseController.
-void BookmarkEditor::Show(gfx::NativeWindow parent_hwnd,
- Profile* profile,
- const BookmarkNode* parent,
- const EditDetails& details,
- Configuration configuration) {
- BookmarkEditorBaseController* controller = nil;
- if (details.type == EditDetails::NEW_FOLDER) {
- controller = [[BookmarkAllTabsController alloc]
- initWithParentWindow:parent_hwnd
- profile:profile
- parent:parent
- configuration:configuration];
- } else {
- controller = [[BookmarkEditorController alloc]
- initWithParentWindow:parent_hwnd
- profile:profile
- parent:parent
- node:details.existing_node
- configuration:configuration];
- }
- [controller runAsModalSheet];
-}
-
-// Adapter to tell BookmarkEditorBaseController when bookmarks change.
-class BookmarkEditorBaseControllerBridge : public BookmarkModelObserver {
- public:
- BookmarkEditorBaseControllerBridge(BookmarkEditorBaseController* controller)
- : controller_(controller),
- importing_(false)
- { }
-
- virtual void Loaded(BookmarkModel* model) {
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- virtual void BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index) {
- if (!importing_ && new_parent->GetChild(new_index)->is_folder())
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- virtual void BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index) {
- if (!importing_ && parent->GetChild(index)->is_folder())
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- virtual void BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node) {
- [controller_ nodeRemoved:node fromParent:parent];
- if (node->is_folder())
- [controller_ modelChangedPreserveSelection:NO];
- }
-
- virtual void BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node) {
- if (!importing_ && node->is_folder())
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
- const BookmarkNode* node) {
- if (!importing_)
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node) {
- // I care nothing for these 'favicons': I only show folders.
- }
-
- virtual void BookmarkImportBeginning(BookmarkModel* model) {
- importing_ = true;
- }
-
- // Invoked after a batch import finishes. This tells observers to update
- // themselves if they were waiting for the update to finish.
- virtual void BookmarkImportEnding(BookmarkModel* model) {
- importing_ = false;
- [controller_ modelChangedPreserveSelection:YES];
- }
-
- private:
- BookmarkEditorBaseController* controller_; // weak
- bool importing_;
-};
-
-
-#pragma mark -
-
-@implementation BookmarkEditorBaseController
-
-@synthesize initialName = initialName_;
-@synthesize displayName = displayName_;
-@synthesize okEnabled = okEnabled_;
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- nibName:(NSString*)nibName
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- configuration:(BookmarkEditor::Configuration)configuration {
- NSString* nibpath = [mac_util::MainAppBundle()
- pathForResource:nibName
- ofType:@"nib"];
- if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
- parentWindow_ = parentWindow;
- profile_ = profile;
- parentNode_ = parent;
- configuration_ = configuration;
- initialName_ = [@"" retain];
- observer_.reset(new BookmarkEditorBaseControllerBridge(self));
- [self bookmarkModel]->AddObserver(observer_.get());
- }
- return self;
-}
-
-- (void)dealloc {
- [self bookmarkModel]->RemoveObserver(observer_.get());
- [initialName_ release];
- [displayName_ release];
- [super dealloc];
-}
-
-- (void)awakeFromNib {
- [self setDisplayName:[self initialName]];
-
- if (configuration_ != BookmarkEditor::SHOW_TREE) {
- // Remember the tree view's height; we will shrink our frame by that much.
- NSRect frame = [[self window] frame];
- CGFloat browserHeight = [folderTreeView_ frame].size.height;
- frame.size.height -= browserHeight;
- frame.origin.y += browserHeight;
- // Remove the folder tree and "new folder" button.
- [folderTreeView_ removeFromSuperview];
- [newFolderButton_ removeFromSuperview];
- // Finally, commit the size change.
- [[self window] setFrame:frame display:YES];
- }
-
- // Build up a tree of the current folder configuration.
- [self buildFolderTree];
-}
-
-- (void)windowDidLoad {
- if (configuration_ == BookmarkEditor::SHOW_TREE) {
- [self selectNodeInBrowser:parentNode_];
- }
-}
-
-/* TODO(jrg):
-// Implementing this informal protocol allows us to open the sheet
-// somewhere other than at the top of the window. NOTE: this means
-// that I, the controller, am also the window's delegate.
-- (NSRect)window:(NSWindow*)window willPositionSheet:(NSWindow*)sheet
- usingRect:(NSRect)rect {
- // adjust rect.origin.y to be the bottom of the toolbar
- return rect;
-}
-*/
-
-// TODO(jrg): consider NSModalSession.
-- (void)runAsModalSheet {
- // Lock down floating bar when in full-screen mode. Don't animate
- // otherwise the pane will be misplaced.
- [[BrowserWindowController browserWindowControllerForWindow:parentWindow_]
- lockBarVisibilityForOwner:self withAnimation:NO delay:NO];
- [NSApp beginSheet:[self window]
- modalForWindow:parentWindow_
- modalDelegate:self
- didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
- contextInfo:nil];
-}
-
-- (BOOL)okEnabled {
- return YES;
-}
-
-- (IBAction)ok:(id)sender {
- // At least one of these two functions should be provided by derived classes.
- BOOL hasWillCommit = [self respondsToSelector:@selector(willCommit)];
- BOOL hasDidCommit = [self respondsToSelector:@selector(didCommit)];
- DCHECK(hasWillCommit || hasDidCommit);
- BOOL shouldContinue = YES;
- if (hasWillCommit) {
- NSNumber* hasWillContinue = [self performSelector:@selector(willCommit)];
- if (hasWillContinue && [hasWillContinue isKindOfClass:[NSNumber class]])
- shouldContinue = [hasWillContinue boolValue];
- }
- if (shouldContinue)
- [self createNewFolders];
- if (hasDidCommit) {
- NSNumber* hasDidContinue = [self performSelector:@selector(didCommit)];
- if (hasDidContinue && [hasDidContinue isKindOfClass:[NSNumber class]])
- shouldContinue = [hasDidContinue boolValue];
- }
- if (shouldContinue)
- [NSApp endSheet:[self window]];
-}
-
-- (IBAction)cancel:(id)sender {
- [NSApp endSheet:[self window]];
-}
-
-- (void)didEndSheet:(NSWindow*)sheet
- returnCode:(int)returnCode
- contextInfo:(void*)contextInfo {
- [sheet close];
- [[BrowserWindowController browserWindowControllerForWindow:parentWindow_]
- releaseBarVisibilityForOwner:self withAnimation:YES delay:NO];
-}
-
-- (void)windowWillClose:(NSNotification*)notification {
- [self autorelease];
-}
-
-#pragma mark Folder Tree Management
-
-- (BookmarkModel*)bookmarkModel {
- return profile_->GetBookmarkModel();
-}
-
-- (const BookmarkNode*)parentNode {
- return parentNode_;
-}
-
-- (BookmarkFolderInfo*)folderForIndexPath:(NSIndexPath*)indexPath {
- NSUInteger pathCount = [indexPath length];
- BookmarkFolderInfo* item = nil;
- NSArray* treeNode = [self folderTreeArray];
- for (NSUInteger i = 0; i < pathCount; ++i) {
- item = [treeNode objectAtIndex:[indexPath indexAtPosition:i]];
- treeNode = [item children];
- }
- return item;
-}
-
-- (NSIndexPath*)selectedIndexPath {
- NSIndexPath* selectedIndexPath = nil;
- NSArray* selections = [self tableSelectionPaths];
- if ([selections count]) {
- DCHECK([selections count] == 1); // Should be exactly one selection.
- selectedIndexPath = [selections objectAtIndex:0];
- }
- return selectedIndexPath;
-}
-
-- (BookmarkFolderInfo*)selectedFolder {
- BookmarkFolderInfo* item = nil;
- NSIndexPath* selectedIndexPath = [self selectedIndexPath];
- if (selectedIndexPath) {
- item = [self folderForIndexPath:selectedIndexPath];
- }
- return item;
-}
-
-- (const BookmarkNode*)selectedNode {
- const BookmarkNode* selectedNode = NULL;
- // Determine a new parent node only if the browser is showing.
- if (configuration_ == BookmarkEditor::SHOW_TREE) {
- BookmarkFolderInfo* folderInfo = [self selectedFolder];
- if (folderInfo)
- selectedNode = [folderInfo folderNode];
- } else {
- // If the tree is not showing then we use the original parent.
- selectedNode = parentNode_;
- }
- return selectedNode;
-}
-
-- (NSArray*)folderTreeArray {
- return folderTreeArray_.get();
-}
-
-- (NSArray*)tableSelectionPaths {
- return tableSelectionPaths_.get();
-}
-
-- (void)setTableSelectionPath:(NSIndexPath*)tableSelectionPath {
- [self setTableSelectionPaths:[NSArray arrayWithObject:tableSelectionPath]];
-}
-
-- (void)setTableSelectionPaths:(NSArray*)tableSelectionPaths {
- tableSelectionPaths_.reset([tableSelectionPaths retain]);
-}
-
-- (void)selectNodeInBrowser:(const BookmarkNode*)node {
- DCHECK(configuration_ == BookmarkEditor::SHOW_TREE);
- NSIndexPath* selectionPath = [self selectionPathForNode:node];
- [self willChangeValueForKey:@"okEnabled"];
- [self setTableSelectionPath:selectionPath];
- [self didChangeValueForKey:@"okEnabled"];
-}
-
-- (NSIndexPath*)selectionPathForNode:(const BookmarkNode*)desiredNode {
- // Back up the parent chaing for desiredNode, building up a stack
- // of ancestor nodes. Then crawl down the folderTreeArray looking
- // for each ancestor in order while building up the selectionPath.
- std::stack<const BookmarkNode*> nodeStack;
- BookmarkModel* model = profile_->GetBookmarkModel();
- const BookmarkNode* rootNode = model->root_node();
- const BookmarkNode* node = desiredNode;
- while (node != rootNode) {
- DCHECK(node);
- nodeStack.push(node);
- node = node->GetParent();
- }
- NSUInteger stackSize = nodeStack.size();
-
- NSIndexPath* path = nil;
- NSArray* folders = [self folderTreeArray];
- while (!nodeStack.empty()) {
- node = nodeStack.top();
- nodeStack.pop();
- // Find node in the current folders array.
- NSUInteger i = 0;
- for (BookmarkFolderInfo *folderInfo in folders) {
- const BookmarkNode* testNode = [folderInfo folderNode];
- if (testNode == node) {
- path = path ? [path indexPathByAddingIndex:i] :
- [NSIndexPath indexPathWithIndex:i];
- folders = [folderInfo children];
- break;
- }
- ++i;
- }
- }
- DCHECK([path length] == stackSize);
- return path;
-}
-
-- (NSMutableArray*)addChildFoldersFromNode:(const BookmarkNode*)node {
- NSMutableArray* childFolders = nil;
- int childCount = node->GetChildCount();
- for (int i = 0; i < childCount; ++i) {
- const BookmarkNode* childNode = node->GetChild(i);
- if (childNode->type() != BookmarkNode::URL) {
- NSString* childName = base::SysUTF16ToNSString(childNode->GetTitle());
- NSMutableArray* children = [self addChildFoldersFromNode:childNode];
- BookmarkFolderInfo* folderInfo =
- [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:childName
- folderNode:childNode
- children:children];
- if (!childFolders)
- childFolders = [NSMutableArray arrayWithObject:folderInfo];
- else
- [childFolders addObject:folderInfo];
- }
- }
- return childFolders;
-}
-
-- (void)buildFolderTree {
- // Build up a tree of the current folder configuration.
- BookmarkModel* model = profile_->GetBookmarkModel();
- const BookmarkNode* rootNode = model->root_node();
- NSMutableArray* baseArray = [self addChildFoldersFromNode:rootNode];
- DCHECK(baseArray);
- [self willChangeValueForKey:@"folderTreeArray"];
- folderTreeArray_.reset([baseArray retain]);
- [self didChangeValueForKey:@"folderTreeArray"];
-}
-
-- (void)modelChangedPreserveSelection:(BOOL)preserve {
- const BookmarkNode* selectedNode = [self selectedNode];
- [self buildFolderTree];
- if (preserve &&
- selectedNode &&
- configuration_ == BookmarkEditor::SHOW_TREE)
- [self selectNodeInBrowser:selectedNode];
-}
-
-- (void)nodeRemoved:(const BookmarkNode*)node
- fromParent:(const BookmarkNode*)parent {
- if (node->is_folder()) {
- if (parentNode_ == node || parentNode_->HasAncestor(node)) {
- parentNode_ = [self bookmarkModel]->GetBookmarkBarNode();
- if (configuration_ != BookmarkEditor::SHOW_TREE) {
- // The user can't select a different folder, so just close up shop.
- [self cancel:self];
- return;
- }
- }
-
- if (configuration_ == BookmarkEditor::SHOW_TREE) {
- // For safety's sake, in case deleted node was an ancestor of selection,
- // go back to a known safe place.
- [self selectNodeInBrowser:parentNode_];
- }
- }
-}
-
-#pragma mark New Folder Handler
-
-- (void)createNewFoldersForFolder:(BookmarkFolderInfo*)folderInfo
- selectedFolderInfo:(BookmarkFolderInfo*)selectedFolderInfo {
- NSArray* subfolders = [folderInfo children];
- const BookmarkNode* parentNode = [folderInfo folderNode];
- DCHECK(parentNode);
- NSUInteger i = 0;
- for (BookmarkFolderInfo* subFolderInfo in subfolders) {
- if ([subFolderInfo newFolder]) {
- BookmarkModel* model = [self bookmarkModel];
- const BookmarkNode* newFolder =
- model->AddGroup(parentNode, i,
- base::SysNSStringToUTF16([subFolderInfo folderName]));
- // Update our dictionary with the actual folder node just created.
- [subFolderInfo setFolderNode:newFolder];
- [subFolderInfo setNewFolder:NO];
- // If the newly created folder was selected, update the selection path.
- if (subFolderInfo == selectedFolderInfo) {
- NSIndexPath* selectionPath = [self selectionPathForNode:newFolder];
- [self setTableSelectionPath:selectionPath];
- }
- }
- [self createNewFoldersForFolder:subFolderInfo
- selectedFolderInfo:selectedFolderInfo];
- ++i;
- }
-}
-
-- (IBAction)newFolder:(id)sender {
- // Create a new folder off of the selected folder node.
- BookmarkFolderInfo* parentInfo = [self selectedFolder];
- if (parentInfo) {
- NSIndexPath* selection = [self selectedIndexPath];
- NSString* newFolderName =
- l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
- BookmarkFolderInfo* folderInfo =
- [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:newFolderName];
- [self willChangeValueForKey:@"folderTreeArray"];
- NSMutableArray* children = [parentInfo children];
- if (children) {
- [children addObject:folderInfo];
- } else {
- children = [NSMutableArray arrayWithObject:folderInfo];
- [parentInfo setChildren:children];
- }
- [self didChangeValueForKey:@"folderTreeArray"];
-
- // Expose the parent folder children.
- [folderTreeView_ expandItem:parentInfo];
-
- // Select the new folder node and put the folder name into edit mode.
- selection = [selection indexPathByAddingIndex:[children count] - 1];
- [self setTableSelectionPath:selection];
- NSInteger row = [folderTreeView_ selectedRow];
- DCHECK(row >= 0);
- [folderTreeView_ editColumn:0 row:row withEvent:nil select:YES];
- }
-}
-
-- (void)createNewFolders {
- // Turn off notifications while "importing" folders (as created in the sheet).
- observer_->BookmarkImportBeginning([self bookmarkModel]);
- // Scan the tree looking for nodes marked 'newFolder' and create those nodes.
- NSArray* folderTreeArray = [self folderTreeArray];
- for (BookmarkFolderInfo *folderInfo in folderTreeArray) {
- [self createNewFoldersForFolder:folderInfo
- selectedFolderInfo:[self selectedFolder]];
- }
- // Notifications back on.
- observer_->BookmarkImportEnding([self bookmarkModel]);
-}
-
-#pragma mark For Unit Test Use Only
-
-- (BOOL)okButtonEnabled {
- return [okButton_ isEnabled];
-}
-
-- (void)selectTestNodeInBrowser:(const BookmarkNode*)node {
- [self selectNodeInBrowser:node];
-}
-
-@end // BookmarkEditorBaseController
-
-@implementation BookmarkFolderInfo
-
-@synthesize folderName = folderName_;
-@synthesize folderNode = folderNode_;
-@synthesize children = children_;
-@synthesize newFolder = newFolder_;
-
-+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName
- folderNode:(const BookmarkNode*)folderNode
- children:(NSMutableArray*)children {
- return [[[BookmarkFolderInfo alloc] initWithFolderName:folderName
- folderNode:folderNode
- children:children
- newFolder:NO]
- autorelease];
-}
-
-+ (id)bookmarkFolderInfoWithFolderName:(NSString*)folderName {
- return [[[BookmarkFolderInfo alloc] initWithFolderName:folderName
- folderNode:NULL
- children:nil
- newFolder:YES]
- autorelease];
-}
-
-- (id)initWithFolderName:(NSString*)folderName
- folderNode:(const BookmarkNode*)folderNode
- children:(NSMutableArray*)children
- newFolder:(BOOL)newFolder {
- if ((self = [super init])) {
- // A folderName is always required, and if newFolder is NO then there
- // should be a folderNode. Children is optional.
- DCHECK(folderName && (newFolder || folderNode));
- if (folderName && (newFolder || folderNode)) {
- folderName_ = [folderName copy];
- folderNode_ = folderNode;
- children_ = [children retain];
- newFolder_ = newFolder;
- } else {
- NOTREACHED(); // Invalid init.
- [self release];
- self = nil;
- }
- }
- return self;
-}
-
-- (id)init {
- NOTREACHED(); // Should never be called.
- return [self initWithFolderName:nil folderNode:nil children:nil newFolder:NO];
-}
-
-- (void)dealloc {
- [folderName_ release];
- [children_ release];
- [super dealloc];
-}
-
-// Implementing isEqual: allows the NSTreeController to preserve the selection
-// and open/shut state of outline items when the data changes.
-- (BOOL)isEqual:(id)other {
- return [other isKindOfClass:[BookmarkFolderInfo class]] &&
- folderNode_ == [(BookmarkFolderInfo*)other folderNode];
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm
deleted file mode 100644
index daac540..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller_unittest.mm
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "app/l10n_util_mac.h"
-#include "base/scoped_nsobject.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "grit/generated_resources.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-class BookmarkEditorBaseControllerTest : public CocoaTest {
- public:
- BrowserTestHelper browser_helper_;
- BookmarkEditorBaseController* controller_; // weak
- const BookmarkNode* group_a_;
- const BookmarkNode* group_b_;
- const BookmarkNode* group_b_0_;
- const BookmarkNode* group_b_3_;
- const BookmarkNode* group_c_;
-
- BookmarkEditorBaseControllerTest() {
- // Set up a small bookmark hierarchy, which will look as follows:
- // a b c d
- // a-0 b-0 c-0
- // a-1 b-00 c-1
- // a-2 b-1 c-2
- // b-2 c-3
- // b-3
- // b-30
- // b-31
- // b-4
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- const BookmarkNode* root = model.GetBookmarkBarNode();
- group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a"));
- model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com"));
- model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com"));
- model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com"));
-
- group_b_ = model.AddGroup(root, 1, ASCIIToUTF16("b"));
- group_b_0_ = model.AddGroup(group_b_, 0, ASCIIToUTF16("b-0"));
- model.AddURL(group_b_0_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com"));
- model.AddURL(group_b_, 1, ASCIIToUTF16("b-1"), GURL("http://b-1.com"));
- model.AddURL(group_b_, 2, ASCIIToUTF16("b-2"), GURL("http://b-2.com"));
- group_b_3_ = model.AddGroup(group_b_, 3, ASCIIToUTF16("b-3"));
- model.AddURL(group_b_3_, 0, ASCIIToUTF16("b-30"), GURL("http://b-30.com"));
- model.AddURL(group_b_3_, 1, ASCIIToUTF16("b-31"), GURL("http://b-31.com"));
- model.AddURL(group_b_, 4, ASCIIToUTF16("b-4"), GURL("http://b-4.com"));
-
- group_c_ = model.AddGroup(root, 2, ASCIIToUTF16("c"));
- model.AddURL(group_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com"));
- model.AddURL(group_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com"));
- model.AddURL(group_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com"));
- model.AddURL(group_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com"));
-
- model.AddURL(root, 3, ASCIIToUTF16("d"), GURL("http://d-0.com"));
- }
-
- virtual BookmarkEditorBaseController* CreateController() {
- return [[BookmarkEditorBaseController alloc]
- initWithParentWindow:test_window()
- nibName:@"BookmarkAllTabs"
- profile:browser_helper_.profile()
- parent:group_b_0_
- configuration:BookmarkEditor::SHOW_TREE];
- }
-
- virtual void SetUp() {
- CocoaTest::SetUp();
- controller_ = CreateController();
- EXPECT_TRUE([controller_ window]);
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-};
-
-TEST_F(BookmarkEditorBaseControllerTest, VerifyBookmarkTestModel) {
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- const BookmarkNode& root(*model.GetBookmarkBarNode());
- EXPECT_EQ(4, root.GetChildCount());
- // a
- const BookmarkNode* child = root.GetChild(0);
- EXPECT_EQ(3, child->GetChildCount());
- const BookmarkNode* subchild = child->GetChild(0);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
- // b
- child = root.GetChild(1);
- EXPECT_EQ(5, child->GetChildCount());
- subchild = child->GetChild(0);
- EXPECT_EQ(1, subchild->GetChildCount());
- const BookmarkNode* subsubchild = subchild->GetChild(0);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(3);
- EXPECT_EQ(2, subchild->GetChildCount());
- subsubchild = subchild->GetChild(0);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subsubchild = subchild->GetChild(1);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subchild = child->GetChild(4);
- EXPECT_EQ(0, subchild->GetChildCount());
- // c
- child = root.GetChild(2);
- EXPECT_EQ(4, child->GetChildCount());
- subchild = child->GetChild(0);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(3);
- EXPECT_EQ(0, subchild->GetChildCount());
- // d
- child = root.GetChild(3);
- EXPECT_EQ(0, child->GetChildCount());
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, NodeSelection) {
- EXPECT_TRUE([controller_ folderTreeArray]);
- [controller_ selectTestNodeInBrowser:group_b_3_];
- const BookmarkNode* node = [controller_ selectedNode];
- EXPECT_EQ(node, group_b_3_);
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, CreateFolder) {
- EXPECT_EQ(2, group_b_3_->GetChildCount());
- [controller_ selectTestNodeInBrowser:group_b_3_];
- NSString* expectedName =
- l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
- [controller_ setDisplayName:expectedName];
- [controller_ newFolder:nil];
- NSArray* selectionPaths = [controller_ tableSelectionPaths];
- EXPECT_EQ(1U, [selectionPaths count]);
- NSIndexPath* selectionPath = [selectionPaths objectAtIndex:0];
- EXPECT_EQ(4U, [selectionPath length]);
- BookmarkFolderInfo* newFolderInfo = [controller_ selectedFolder];
- EXPECT_TRUE(newFolderInfo);
- NSString* newFolderName = [newFolderInfo folderName];
- EXPECT_NSEQ(expectedName, newFolderName);
- [controller_ createNewFolders];
- // Verify that the tab folder was added to the new folder.
- EXPECT_EQ(3, group_b_3_->GetChildCount());
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, CreateTwoFolders) {
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- const BookmarkNode* bar = model->GetBookmarkBarNode();
- // Create 2 folders which are children of the bar.
- [controller_ selectTestNodeInBrowser:bar];
- [controller_ newFolder:nil];
- [controller_ selectTestNodeInBrowser:bar];
- [controller_ newFolder:nil];
- // If we do NOT crash on createNewFolders, success!
- // (e.g. http://crbug.com/47877 is fixed).
- [controller_ createNewFolders];
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, SelectedFolderDeleted) {
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- [controller_ selectTestNodeInBrowser:group_b_3_];
- EXPECT_EQ(group_b_3_, [controller_ selectedNode]);
-
- // Delete the selected node, and verify it's no longer selected:
- model.Remove(group_b_, 3);
- EXPECT_NE(group_b_3_, [controller_ selectedNode]);
-
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, SelectedFoldersParentDeleted) {
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- const BookmarkNode* root = model.GetBookmarkBarNode();
- [controller_ selectTestNodeInBrowser:group_b_3_];
- EXPECT_EQ(group_b_3_, [controller_ selectedNode]);
-
- // Delete the selected node's parent, and verify it's no longer selected:
- model.Remove(root, 1);
- EXPECT_NE(group_b_3_, [controller_ selectedNode]);
-
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorBaseControllerTest, FolderAdded) {
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- const BookmarkNode* root = model.GetBookmarkBarNode();
-
- // Add a group node to the model, and verify it can be selected in the tree:
- const BookmarkNode* group_added = model.AddGroup(root, 0,
- ASCIIToUTF16("added"));
- [controller_ selectTestNodeInBrowser:group_added];
- EXPECT_EQ(group_added, [controller_ selectedNode]);
-
- [controller_ cancel:nil];
-}
-
-
-class BookmarkFolderInfoTest : public CocoaTest { };
-
-TEST_F(BookmarkFolderInfoTest, Construction) {
- NSMutableArray* children = [NSMutableArray arrayWithObject:@"child"];
- // We just need a pointer, and any pointer will do.
- const BookmarkNode* fakeNode =
- reinterpret_cast<const BookmarkNode*>(&children);
- BookmarkFolderInfo* info =
- [BookmarkFolderInfo bookmarkFolderInfoWithFolderName:@"name"
- folderNode:fakeNode
- children:children];
- EXPECT_TRUE(info);
- EXPECT_EQ([info folderName], @"name");
- EXPECT_EQ([info children], children);
- EXPECT_EQ([info folderNode], fakeNode);
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h
deleted file mode 100644
index 11bd58c..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_EDITOR_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_EDITOR_CONTROLLER_H_
-#pragma once
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_base_controller.h"
-
-// A controller for the bookmark editor, opened by 1) Edit... from the
-// context menu of a bookmark button, and 2) Bookmark this Page...'s Edit
-// button.
-@interface BookmarkEditorController : BookmarkEditorBaseController {
- @private
- const BookmarkNode* node_; // weak; owned by the model
- scoped_nsobject<NSString> initialUrl_;
- NSString* displayURL_; // Bound to a text field in the dialog.
- IBOutlet NSTextField* urlField_;
-}
-
-@property (nonatomic, copy) NSString* displayURL;
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- node:(const BookmarkNode*)node
- configuration:(BookmarkEditor::Configuration)configuration;
-
-@end
-
-@interface BookmarkEditorController (UnitTesting)
-- (NSColor *)urlFieldColor;
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_EDITOR_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.mm
deleted file mode 100644
index 14500c9..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller.mm
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h"
-
-#include "app/l10n_util.h"
-#include "base/string16.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-
-@interface BookmarkEditorController (Private)
-
-// Grab the url from the text field and convert.
-- (GURL)GURLFromUrlField;
-
-@end
-
-@implementation BookmarkEditorController
-
-@synthesize displayURL = displayURL_;
-
-+ (NSSet*)keyPathsForValuesAffectingOkEnabled {
- return [NSSet setWithObject:@"displayURL"];
-}
-
-- (id)initWithParentWindow:(NSWindow*)parentWindow
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- node:(const BookmarkNode*)node
- configuration:(BookmarkEditor::Configuration)configuration {
- if ((self = [super initWithParentWindow:parentWindow
- nibName:@"BookmarkEditor"
- profile:profile
- parent:parent
- configuration:configuration])) {
- // "Add Page..." has no "node" so this may be NULL.
- node_ = node;
- }
- return self;
-}
-
-- (void)dealloc {
- [displayURL_ release];
- [super dealloc];
-}
-
-- (void)awakeFromNib {
- // Set text fields to match our bookmark. If the node is NULL we
- // arrived here from an "Add Page..." item in a context menu.
- if (node_) {
- [self setInitialName:base::SysUTF16ToNSString(node_->GetTitle())];
- std::string url_string = node_->GetURL().possibly_invalid_spec();
- initialUrl_.reset([[NSString stringWithUTF8String:url_string.c_str()]
- retain]);
- } else {
- initialUrl_.reset([@"" retain]);
- }
- [self setDisplayURL:initialUrl_];
- [super awakeFromNib];
-}
-
-- (void)nodeRemoved:(const BookmarkNode*)node
- fromParent:(const BookmarkNode*)parent
-{
- // Be conservative; it is needed (e.g. "Add Page...")
- node_ = NULL;
- [self cancel:self];
-}
-
-#pragma mark Bookmark Editing
-
-// If possible, return a valid GURL from the URL text field.
-- (GURL)GURLFromUrlField {
- NSString* url = [self displayURL];
- GURL newURL = GURL([url UTF8String]);
- if (!newURL.is_valid()) {
- // Mimic observed friendliness from Windows
- newURL = GURL([[NSString stringWithFormat:@"http://%@", url] UTF8String]);
- }
- return newURL;
-}
-
-// Enable the OK button if there is a valid URL.
-- (BOOL)okEnabled {
- BOOL okEnabled = NO;
- if ([[self displayURL] length]) {
- GURL newURL = [self GURLFromUrlField];
- okEnabled = (newURL.is_valid()) ? YES : NO;
- }
- if (okEnabled)
- [urlField_ setBackgroundColor:[NSColor whiteColor]];
- else
- [urlField_ setBackgroundColor:[NSColor colorWithCalibratedRed:1.0
- green:0.67
- blue:0.67
- alpha:1.0]];
- return okEnabled;
-}
-
-// The the bookmark's URL is assumed to be valid (otherwise the OK button
-// should not be enabled). Previously existing bookmarks for which the
-// parent has not changed are updated in-place. Those for which the parent
-// has changed are removed with a new node created under the new parent.
-// Called by -[BookmarkEditorBaseController ok:].
-- (NSNumber*)didCommit {
- NSString* name = [[self displayName] stringByTrimmingCharactersInSet:
- [NSCharacterSet newlineCharacterSet]];
- string16 newTitle = base::SysNSStringToUTF16(name);
- const BookmarkNode* newParentNode = [self selectedNode];
- GURL newURL = [self GURLFromUrlField];
- if (!newURL.is_valid()) {
- // Shouldn't be reached -- OK button should be disabled if not valid!
- NOTREACHED();
- return [NSNumber numberWithBool:NO];
- }
-
- // Determine where the new/replacement bookmark is to go.
- BookmarkModel* model = [self bookmarkModel];
- // If there was an old node then we update the node, and move it to its new
- // parent if the parent has changed (rather than deleting it from the old
- // parent and adding to the new -- which also prevents the 'poofing' that
- // occurs when a node is deleted).
- if (node_) {
- model->SetURL(node_, newURL);
- model->SetTitle(node_, newTitle);
- const BookmarkNode* oldParentNode = [self parentNode];
- if (newParentNode != oldParentNode)
- model->Move(node_, newParentNode, newParentNode->GetChildCount());
- } else {
- // Otherwise, add a new bookmark at the end of the newly selected folder.
- model->AddURL(newParentNode, newParentNode->GetChildCount(), newTitle,
- newURL);
- }
- return [NSNumber numberWithBool:YES];
-}
-
-- (NSColor *)urlFieldColor {
- return [urlField_ backgroundColor];
-}
-
-@end // BookmarkEditorController
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_editor_controller_unittest.mm
deleted file mode 100644
index e19898d..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_editor_controller_unittest.mm
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/string16.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_editor_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-class BookmarkEditorControllerTest : public CocoaTest {
- public:
- BrowserTestHelper browser_helper_;
- const BookmarkNode* default_node_;
- const BookmarkNode* default_parent_;
- const char* default_name_;
- string16 default_title_;
- BookmarkEditorController* controller_;
-
- virtual void SetUp() {
- CocoaTest::SetUp();
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- default_parent_ = model->GetBookmarkBarNode();
- default_name_ = "http://www.zim-bop-a-dee.com/";
- default_title_ = ASCIIToUTF16("ooh title");
- const BookmarkNode* default_node = model->AddURL(default_parent_, 0,
- default_title_,
- GURL(default_name_));
- controller_ = [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:browser_helper_.profile()
- parent:default_parent_
- node:default_node
- configuration:BookmarkEditor::NO_TREE];
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-};
-
-TEST_F(BookmarkEditorControllerTest, NoEdit) {
- [controller_ cancel:nil];
- ASSERT_EQ(default_parent_->GetChildCount(), 1);
- const BookmarkNode* child = default_parent_->GetChild(0);
- EXPECT_EQ(child->GetTitle(), default_title_);
- EXPECT_EQ(child->GetURL(), GURL(default_name_));
-}
-
-TEST_F(BookmarkEditorControllerTest, EditTitle) {
- [controller_ setDisplayName:@"whamma jamma bamma"];
- [controller_ ok:nil];
- ASSERT_EQ(default_parent_->GetChildCount(), 1);
- const BookmarkNode* child = default_parent_->GetChild(0);
- EXPECT_EQ(child->GetTitle(), ASCIIToUTF16("whamma jamma bamma"));
- EXPECT_EQ(child->GetURL(), GURL(default_name_));
-}
-
-TEST_F(BookmarkEditorControllerTest, EditURL) {
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ setDisplayURL:@"http://yellow-sneakers.com/"];
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ ok:nil];
- ASSERT_EQ(default_parent_->GetChildCount(), 1);
- const BookmarkNode* child = default_parent_->GetChild(0);
- EXPECT_EQ(child->GetTitle(), default_title_);
- EXPECT_EQ(child->GetURL(), GURL("http://yellow-sneakers.com/"));
-}
-
-TEST_F(BookmarkEditorControllerTest, EditAndFixPrefix) {
- [controller_ setDisplayURL:@"x"];
- [controller_ ok:nil];
- ASSERT_EQ(default_parent_->GetChildCount(), 1);
- const BookmarkNode* child = default_parent_->GetChild(0);
- EXPECT_TRUE(child->GetURL().is_valid());
-}
-
-TEST_F(BookmarkEditorControllerTest, NodeDeleted) {
- // Delete the bookmark being edited and verify the sheet cancels itself:
- ASSERT_TRUE([test_window() attachedSheet]);
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- model->Remove(default_parent_, 0);
- ASSERT_FALSE([test_window() attachedSheet]);
-}
-
-TEST_F(BookmarkEditorControllerTest, EditAndConfirmOKButton) {
- // Confirm OK button enabled/disabled as appropriate:
- // First test the URL.
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ setDisplayURL:@""];
- EXPECT_FALSE([controller_ okButtonEnabled]);
- [controller_ setDisplayURL:@"http://www.cnn.com"];
- EXPECT_TRUE([controller_ okButtonEnabled]);
- // Then test the name.
- [controller_ setDisplayName:@""];
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ setDisplayName:@" "];
- EXPECT_TRUE([controller_ okButtonEnabled]);
- // Then little mix of both.
- [controller_ setDisplayName:@"name"];
- EXPECT_TRUE([controller_ okButtonEnabled]);
- [controller_ setDisplayURL:@""];
- EXPECT_FALSE([controller_ okButtonEnabled]);
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorControllerTest, GoodAndBadURLsChangeColor) {
- // Confirm that the background color of the URL edit field changes
- // based on whether it contains a valid or invalid URL.
- [controller_ setDisplayURL:@"http://www.cnn.com"];
- NSColor *urlColorA = [controller_ urlFieldColor];
- EXPECT_TRUE(urlColorA);
- [controller_ setDisplayURL:@""];
- NSColor *urlColorB = [controller_ urlFieldColor];
- EXPECT_TRUE(urlColorB);
- EXPECT_NSNE(urlColorA, urlColorB);
- [controller_ setDisplayURL:@"http://www.google.com"];
- [controller_ cancel:nil];
- urlColorB = [controller_ urlFieldColor];
- EXPECT_TRUE(urlColorB);
- EXPECT_NSEQ(urlColorA, urlColorB);
-}
-
-class BookmarkEditorControllerNoNodeTest : public CocoaTest {
- public:
- BrowserTestHelper browser_helper_;
- BookmarkEditorController* controller_;
-
- virtual void SetUp() {
- CocoaTest::SetUp();
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- controller_ = [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:browser_helper_.profile()
- parent:parent
- node:NULL
- configuration:BookmarkEditor::NO_TREE];
-
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-};
-
-TEST_F(BookmarkEditorControllerNoNodeTest, NoNodeNoTree) {
- EXPECT_EQ(@"", [controller_ displayName]);
- EXPECT_EQ(@"", [controller_ displayURL]);
- EXPECT_FALSE([controller_ okButtonEnabled]);
- [controller_ cancel:nil];
-}
-
-class BookmarkEditorControllerYesNodeTest : public CocoaTest {
- public:
- BrowserTestHelper browser_helper_;
- string16 default_title_;
- const char* url_name_;
- BookmarkEditorController* controller_;
-
- virtual void SetUp() {
- CocoaTest::SetUp();
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- default_title_ = ASCIIToUTF16("wooh title");
- url_name_ = "http://www.zoom-baby-doo-da.com/";
- const BookmarkNode* node = model->AddURL(parent, 0, default_title_,
- GURL(url_name_));
- controller_ = [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:browser_helper_.profile()
- parent:parent
- node:node
- configuration:BookmarkEditor::NO_TREE];
-
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-};
-
-TEST_F(BookmarkEditorControllerYesNodeTest, YesNodeShowTree) {
- EXPECT_NSEQ(base::SysUTF16ToNSString(default_title_),
- [controller_ displayName]);
- EXPECT_NSEQ([NSString stringWithCString:url_name_
- encoding:NSUTF8StringEncoding],
- [controller_ displayURL]);
- [controller_ cancel:nil];
-}
-
-class BookmarkEditorControllerTreeTest : public CocoaTest {
-
- public:
- BrowserTestHelper browser_helper_;
- BookmarkEditorController* controller_;
- const BookmarkNode* group_a_;
- const BookmarkNode* group_b_;
- const BookmarkNode* group_bb_;
- const BookmarkNode* group_c_;
- const BookmarkNode* bookmark_bb_3_;
- GURL bb3_url_1_;
- GURL bb3_url_2_;
-
- BookmarkEditorControllerTreeTest() {
- // Set up a small bookmark hierarchy, which will look as follows:
- // a b c d
- // a-0 b-0 c-0
- // a-1 bb-0 c-1
- // a-2 bb-1 c-2
- // bb-2
- // bb-3
- // bb-4
- // b-1
- // b-2
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- const BookmarkNode* root = model.GetBookmarkBarNode();
- group_a_ = model.AddGroup(root, 0, ASCIIToUTF16("a"));
- model.AddURL(group_a_, 0, ASCIIToUTF16("a-0"), GURL("http://a-0.com"));
- model.AddURL(group_a_, 1, ASCIIToUTF16("a-1"), GURL("http://a-1.com"));
- model.AddURL(group_a_, 2, ASCIIToUTF16("a-2"), GURL("http://a-2.com"));
-
- group_b_ = model.AddGroup(root, 1, ASCIIToUTF16("b"));
- model.AddURL(group_b_, 0, ASCIIToUTF16("b-0"), GURL("http://b-0.com"));
- group_bb_ = model.AddGroup(group_b_, 1, ASCIIToUTF16("bb"));
- model.AddURL(group_bb_, 0, ASCIIToUTF16("bb-0"), GURL("http://bb-0.com"));
- model.AddURL(group_bb_, 1, ASCIIToUTF16("bb-1"), GURL("http://bb-1.com"));
- model.AddURL(group_bb_, 2, ASCIIToUTF16("bb-2"), GURL("http://bb-2.com"));
-
- // To find it later, this bookmark name must always have a URL
- // of http://bb-3.com or https://bb-3.com
- bb3_url_1_ = GURL("http://bb-3.com");
- bb3_url_2_ = GURL("https://bb-3.com");
- bookmark_bb_3_ = model.AddURL(group_bb_, 3, ASCIIToUTF16("bb-3"),
- bb3_url_1_);
-
- model.AddURL(group_bb_, 4, ASCIIToUTF16("bb-4"), GURL("http://bb-4.com"));
- model.AddURL(group_b_, 2, ASCIIToUTF16("b-1"), GURL("http://b-2.com"));
- model.AddURL(group_b_, 3, ASCIIToUTF16("b-2"), GURL("http://b-3.com"));
-
- group_c_ = model.AddGroup(root, 2, ASCIIToUTF16("c"));
- model.AddURL(group_c_, 0, ASCIIToUTF16("c-0"), GURL("http://c-0.com"));
- model.AddURL(group_c_, 1, ASCIIToUTF16("c-1"), GURL("http://c-1.com"));
- model.AddURL(group_c_, 2, ASCIIToUTF16("c-2"), GURL("http://c-2.com"));
- model.AddURL(group_c_, 3, ASCIIToUTF16("c-3"), GURL("http://c-3.com"));
-
- model.AddURL(root, 3, ASCIIToUTF16("d"), GURL("http://d-0.com"));
- }
-
- virtual BookmarkEditorController* CreateController() {
- return [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:browser_helper_.profile()
- parent:group_bb_
- node:bookmark_bb_3_
- configuration:BookmarkEditor::SHOW_TREE];
- }
-
- virtual void SetUp() {
- controller_ = CreateController();
- [controller_ runAsModalSheet];
- }
-
- virtual void TearDown() {
- controller_ = NULL;
- CocoaTest::TearDown();
- }
-
- // After changing a node, pointers to the node may be invalid. This
- // is because the node itself may not be updated; it may removed and
- // a new one is added in that location. (Implementation detail of
- // BookmarkEditorController). This method updates the class's
- // bookmark_bb_3_ so that it points to the new node for testing.
- void UpdateBB3() {
- std::vector<const BookmarkNode*> nodes;
- BookmarkModel* model = browser_helper_.profile()->GetBookmarkModel();
- model->GetNodesByURL(bb3_url_1_, &nodes);
- if (nodes.size() == 0)
- model->GetNodesByURL(bb3_url_2_, &nodes);
- DCHECK(nodes.size());
- bookmark_bb_3_ = nodes[0];
- }
-
-};
-
-TEST_F(BookmarkEditorControllerTreeTest, VerifyBookmarkTestModel) {
- BookmarkModel& model(*(browser_helper_.profile()->GetBookmarkModel()));
- model.root_node();
- const BookmarkNode& root(*model.GetBookmarkBarNode());
- EXPECT_EQ(4, root.GetChildCount());
- const BookmarkNode* child = root.GetChild(0);
- EXPECT_EQ(3, child->GetChildCount());
- const BookmarkNode* subchild = child->GetChild(0);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
-
- child = root.GetChild(1);
- EXPECT_EQ(4, child->GetChildCount());
- subchild = child->GetChild(0);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(5, subchild->GetChildCount());
- const BookmarkNode* subsubchild = subchild->GetChild(0);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subsubchild = subchild->GetChild(1);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subsubchild = subchild->GetChild(2);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subsubchild = subchild->GetChild(3);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subsubchild = subchild->GetChild(4);
- EXPECT_EQ(0, subsubchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(3);
- EXPECT_EQ(0, subchild->GetChildCount());
-
- child = root.GetChild(2);
- EXPECT_EQ(4, child->GetChildCount());
- subchild = child->GetChild(0);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(1);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(2);
- EXPECT_EQ(0, subchild->GetChildCount());
- subchild = child->GetChild(3);
- EXPECT_EQ(0, subchild->GetChildCount());
-
- child = root.GetChild(3);
- EXPECT_EQ(0, child->GetChildCount());
- [controller_ cancel:nil];
-}
-
-TEST_F(BookmarkEditorControllerTreeTest, RenameBookmarkInPlace) {
- const BookmarkNode* oldParent = bookmark_bb_3_->GetParent();
- [controller_ setDisplayName:@"NEW NAME"];
- [controller_ ok:nil];
- UpdateBB3();
- const BookmarkNode* newParent = bookmark_bb_3_->GetParent();
- ASSERT_EQ(newParent, oldParent);
- int childIndex = newParent->IndexOfChild(bookmark_bb_3_);
- ASSERT_EQ(3, childIndex);
-}
-
-TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkURLInPlace) {
- const BookmarkNode* oldParent = bookmark_bb_3_->GetParent();
- [controller_ setDisplayURL:@"https://bb-3.com"];
- [controller_ ok:nil];
- UpdateBB3();
- const BookmarkNode* newParent = bookmark_bb_3_->GetParent();
- ASSERT_EQ(newParent, oldParent);
- int childIndex = newParent->IndexOfChild(bookmark_bb_3_);
- ASSERT_EQ(3, childIndex);
-}
-
-TEST_F(BookmarkEditorControllerTreeTest, ChangeBookmarkGroup) {
- [controller_ selectTestNodeInBrowser:group_c_];
- [controller_ ok:nil];
- UpdateBB3();
- const BookmarkNode* parent = bookmark_bb_3_->GetParent();
- ASSERT_EQ(parent, group_c_);
- int childIndex = parent->IndexOfChild(bookmark_bb_3_);
- ASSERT_EQ(4, childIndex);
-}
-
-TEST_F(BookmarkEditorControllerTreeTest, ChangeNameAndBookmarkGroup) {
- [controller_ setDisplayName:@"NEW NAME"];
- [controller_ selectTestNodeInBrowser:group_c_];
- [controller_ ok:nil];
- UpdateBB3();
- const BookmarkNode* parent = bookmark_bb_3_->GetParent();
- ASSERT_EQ(parent, group_c_);
- int childIndex = parent->IndexOfChild(bookmark_bb_3_);
- ASSERT_EQ(4, childIndex);
- EXPECT_EQ(bookmark_bb_3_->GetTitle(), ASCIIToUTF16("NEW NAME"));
-}
-
-TEST_F(BookmarkEditorControllerTreeTest, AddFolderWithGroupSelected) {
- // Folders are NOT added unless the OK button is pressed.
- [controller_ newFolder:nil];
- [controller_ cancel:nil];
- EXPECT_EQ(5, group_bb_->GetChildCount());
-}
-
-class BookmarkEditorControllerTreeNoNodeTest :
- public BookmarkEditorControllerTreeTest {
- public:
- virtual BookmarkEditorController* CreateController() {
- return [[BookmarkEditorController alloc]
- initWithParentWindow:test_window()
- profile:browser_helper_.profile()
- parent:group_bb_
- node:nil
- configuration:BookmarkEditor::SHOW_TREE];
- }
-
-};
-
-TEST_F(BookmarkEditorControllerTreeNoNodeTest, NewBookmarkNoNode) {
- [controller_ setDisplayName:@"NEW BOOKMARK"];
- [controller_ setDisplayURL:@"http://NEWURL.com"];
- [controller_ ok:nil];
- const BookmarkNode* new_node = group_bb_->GetChild(5);
- ASSERT_EQ(0, new_node->GetChildCount());
- EXPECT_EQ(new_node->GetTitle(), ASCIIToUTF16("NEW BOOKMARK"));
- EXPECT_EQ(new_node->GetURL(), GURL("http://NEWURL.com"));
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_folder_target.h b/chrome/browser/cocoa/bookmarks/bookmark_folder_target.h
deleted file mode 100644
index c877f72..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_folder_target.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_FOLDER_TARGET_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_FOLDER_TARGET_CONTROLLER_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-@class BookmarkButton;
-@protocol BookmarkButtonControllerProtocol;
-class BookmarkNode;
-
-// Target (in the target/action sense) of a bookmark folder button.
-// Since ObjC doesn't have multiple inheritance we use has-a instead
-// of is-a to share behavior between the BookmarkBarFolderController
-// (NSWindowController) and the BookmarkBarController
-// (NSViewController).
-//
-// This class is unit tested in the context of a BookmarkBarController.
-@interface BookmarkFolderTarget : NSObject {
- // The owner of the bookmark folder button
- id<BookmarkButtonControllerProtocol> controller_; // weak
-}
-
-- (id)initWithController:(id<BookmarkButtonControllerProtocol>)controller;
-
-// Main IBAction for a button click.
-- (IBAction)openBookmarkFolderFromButton:(id)sender;
-
-// Copies the given bookmark node to the given pasteboard, declaring appropriate
-// types (to paste a URL with a title).
-- (void)copyBookmarkNode:(const BookmarkNode*)node
- toPasteboard:(NSPasteboard*)pboard;
-
-// Fill the given pasteboard with appropriate data when the given button is
-// dragged. Since the delegate has no way of providing pasteboard data later,
-// all data must actually be put into the pasteboard and not merely promised.
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button;
-
-@end
-
-// The (internal) |NSPasteboard| type string for bookmark button drags, used for
-// dragging buttons around the bookmark bar. The data for this type is just a
-// pointer to the |BookmarkButton| being dragged.
-extern NSString* kBookmarkButtonDragType;
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_FOLDER_TARGET_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_folder_target.mm b/chrome/browser/cocoa/bookmarks/bookmark_folder_target.mm
deleted file mode 100644
index 3fb1507..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_folder_target.mm
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-
-#include "base/logging.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#import "chrome/browser/cocoa/event_utils.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-
-NSString* kBookmarkButtonDragType = @"ChromiumBookmarkButtonDragType";
-
-@implementation BookmarkFolderTarget
-
-- (id)initWithController:(id<BookmarkButtonControllerProtocol>)controller {
- if ((self = [super init])) {
- controller_ = controller;
- }
- return self;
-}
-
-// This IBAction is called when the user clicks (mouseUp, really) on a
-// "folder" bookmark button. (In this context, "Click" does not
-// include right-click to open a context menu which follows a
-// different path). Scenarios when folder X is clicked:
-// *Predicate* *Action*
-// (nothing) Open Folder X
-// Folder X open Close folder X
-// Folder Y open Close Y, open X
-// Cmd-click Open All with proper disposition
-//
-// Note complication in which a click-drag engages drag and drop, not
-// a click-to-open. Thus the path to get here is a little twisted.
-- (IBAction)openBookmarkFolderFromButton:(id)sender {
- DCHECK(sender);
- // Watch out for a modifier click. For example, command-click
- // should open all.
- //
- // NOTE: we cannot use [[sender cell] mouseDownFlags] because we
- // thwart the normal mouse click mechanism to make buttons
- // draggable. Thus we must use [NSApp currentEvent].
- //
- // Holding command while using the scroll wheel (or moving around
- // over a bookmark folder) can confuse us. Unless we check the
- // event type, we are not sure if this is an "open folder" due to a
- // hover-open or "open folder" due to a click. It doesn't matter
- // (both do the same thing) unless a modifier is held, since
- // command-click should "open all" but command-move should not.
- // WindowOpenDispositionFromNSEvent does not consider the event
- // type; only the modifiers. Thus the need for an extra
- // event-type-check here.
- DCHECK([sender bookmarkNode]->is_folder());
- NSEvent* event = [NSApp currentEvent];
- WindowOpenDisposition disposition =
- event_utils::WindowOpenDispositionFromNSEvent(event);
- if (([event type] != NSMouseEntered) &&
- ([event type] != NSMouseMoved) &&
- ([event type] != NSScrollWheel) &&
- (disposition == NEW_BACKGROUND_TAB)) {
- [controller_ closeAllBookmarkFolders];
- [controller_ openAll:[sender bookmarkNode] disposition:disposition];
- return;
- }
-
- // If click on same folder, close it and be done.
- // Else we clicked on a different folder so more work to do.
- if ([[controller_ folderController] parentButton] == sender) {
- [controller_ closeBookmarkFolder:controller_];
- return;
- }
-
- [controller_ addNewFolderControllerWithParentButton:sender];
-}
-
-- (void)copyBookmarkNode:(const BookmarkNode*)node
- toPasteboard:(NSPasteboard*)pboard {
- if (!node) {
- NOTREACHED();
- return;
- }
-
- if (node->is_folder()) {
- // TODO(viettrungluu): I'm not sure what we should do, so just declare the
- // "additional" types we're given for now. Maybe we want to add a list of
- // URLs? Would we then have to recurse if there were subfolders?
- // In the meanwhile, we *must* set it to a known state. (If this survives to
- // a 10.6-only release, it can be replaced with |-clearContents|.)
- [pboard declareTypes:[NSArray array] owner:nil];
- } else {
- const std::string spec = node->GetURL().spec();
- NSString* url = base::SysUTF8ToNSString(spec);
- NSString* title = base::SysUTF16ToNSString(node->GetTitle());
- [pboard declareURLPasteboardWithAdditionalTypes:[NSArray array]
- owner:nil];
- [pboard setDataForURL:url title:title];
- }
-}
-
-- (void)fillPasteboard:(NSPasteboard*)pboard
- forDragOfButton:(BookmarkButton*)button {
- if (const BookmarkNode* node = [button bookmarkNode]) {
- // Put the bookmark information into the pasteboard, and then write our own
- // data for |kBookmarkButtonDragType|.
- [self copyBookmarkNode:node toPasteboard:pboard];
- [pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]
- owner:nil];
- [pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]
- forType:kBookmarkButtonDragType];
- } else {
- NOTREACHED();
- }
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_folder_target_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_folder_target_unittest.mm
deleted file mode 100644
index 403002d..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_folder_target_unittest.mm
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_folder_target.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_button.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#include "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-#import "third_party/ocmock/OCMock/OCMock.h"
-
-@interface OCMockObject(PreventRetainCycle)
-- (void)clearRecordersAndExpectations;
-@end
-
-@implementation OCMockObject(PreventRetainCycle)
-
-// We need a mechanism to clear the invocation handlers to break a
-// retain cycle (see below; search for "retain cycle").
-- (void)clearRecordersAndExpectations {
- [recorders removeAllObjects];
- [expectations removeAllObjects];
-}
-
-@end
-
-
-class BookmarkFolderTargetTest : public CocoaTest {
- public:
- virtual void SetUp() {
- CocoaTest::SetUp();
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- bmbNode_ = model->GetBookmarkBarNode();
- }
- virtual void TearDown() {
- pool_.Recycle();
- CocoaTest::TearDown();
- }
-
- BrowserTestHelper helper_;
- const BookmarkNode* bmbNode_;
- base::mac::ScopedNSAutoreleasePool pool_;
-};
-
-TEST_F(BookmarkFolderTargetTest, StartWithNothing) {
- // Need a fake "button" which has a bookmark node.
- id sender = [OCMockObject mockForClass:[BookmarkButton class]];
- [[[sender stub] andReturnValue:OCMOCK_VALUE(bmbNode_)] bookmarkNode];
-
- // Fake controller
- id controller = [OCMockObject mockForClass:[BookmarkBarFolderController
- class]];
- // No current folder
- [[[controller stub] andReturn:nil] folderController];
-
- // Make sure we get an addNew
- [[controller expect] addNewFolderControllerWithParentButton:sender];
-
- scoped_nsobject<BookmarkFolderTarget> target(
- [[BookmarkFolderTarget alloc] initWithController:controller]);
-
- [target openBookmarkFolderFromButton:sender];
- [controller verify];
-}
-
-TEST_F(BookmarkFolderTargetTest, ReopenSameFolder) {
- // Need a fake "button" which has a bookmark node.
- id sender = [OCMockObject mockForClass:[BookmarkButton class]];
- [[[sender stub] andReturnValue:OCMOCK_VALUE(bmbNode_)] bookmarkNode];
-
- // Fake controller
- id controller = [OCMockObject mockForClass:[BookmarkBarFolderController
- class]];
- // YES a current folder. Self-mock that as well, so "same" will be
- // true. Note this creates a retain cycle in OCMockObject; we
- // accomodate at the end of this function.
- [[[controller stub] andReturn:controller] folderController];
- [[[controller stub] andReturn:sender] parentButton];
-
- // The folder is open, so a click should close just that folder (and
- // any subfolders).
- [[controller expect] closeBookmarkFolder:controller];
-
- scoped_nsobject<BookmarkFolderTarget> target(
- [[BookmarkFolderTarget alloc] initWithController:controller]);
-
- [target openBookmarkFolderFromButton:sender];
- [controller verify];
-
- // Our use of OCMockObject means an object can return itself. This
- // creates a retain cycle, since OCMock retains all objects used in
- // mock creation. Clear out the invocation handlers of all
- // OCMockRecorders we used to break the cycles.
- [controller clearRecordersAndExpectations];
-}
-
-TEST_F(BookmarkFolderTargetTest, ReopenNotSame) {
- // Need a fake "button" which has a bookmark node.
- id sender = [OCMockObject mockForClass:[BookmarkButton class]];
- [[[sender stub] andReturnValue:OCMOCK_VALUE(bmbNode_)] bookmarkNode];
-
- // Fake controller
- id controller = [OCMockObject mockForClass:[BookmarkBarFolderController
- class]];
- // YES a current folder but NOT same.
- [[[controller stub] andReturn:controller] folderController];
- [[[controller stub] andReturn:nil] parentButton];
-
- // Insure the controller gets a chance to decide which folders to
- // close and open.
- [[controller expect] addNewFolderControllerWithParentButton:sender];
-
- scoped_nsobject<BookmarkFolderTarget> target(
- [[BookmarkFolderTarget alloc] initWithController:controller]);
-
- [target openBookmarkFolderFromButton:sender];
- [controller verify];
-
- // Break retain cycles.
- [controller clearRecordersAndExpectations];
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu.h b/chrome/browser/cocoa/bookmarks/bookmark_menu.h
deleted file mode 100644
index d4ac001..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2009 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/basictypes.h"
-
-
-// The context menu for bookmark buttons needs to know which
-// BookmarkNode it is talking about. For example, "Open All" is
-// disabled if the bookmark node is a folder and has no children.
-@interface BookmarkMenu : NSMenu {
- @private
- int64 id_; // id of the bookmark node we represent.
-}
-- (void)setRepresentedObject:(id)object;
-@property (nonatomic) int64 id;
-@end
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu.mm
deleted file mode 100644
index 9be848b..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu.mm
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2009 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-
-
-@implementation BookmarkMenu
-
-@synthesize id = id_;
-
-// Convention in the bookmark bar controller: the bookmark button
-// cells have a BookmarkNode as their represented object. This object
-// is placed in a BookmarkMenu at the time a cell is asked for its
-// menu.
-- (void)setRepresentedObject:(id)object {
- if ([object isKindOfClass:[NSNumber class]]) {
- id_ = static_cast<int64>([object longLongValue]);
- }
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h b/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h
deleted file mode 100644
index bc606fc..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2010 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.
-
-// C++ controller for the bookmark menu; one per AppController (which
-// means there is only one). When bookmarks are changed, this class
-// takes care of updating Cocoa bookmark menus. This is not named
-// BookmarkMenuController to help avoid confusion between languages.
-// This class needs to be C++, not ObjC, since it derives from
-// BookmarkModelObserver.
-//
-// Most Chromium Cocoa menu items are static from a nib (e.g. New
-// Tab), but may be enabled/disabled under certain circumstances
-// (e.g. Cut and Paste). In addition, most Cocoa menu items have
-// firstResponder: as a target. Unusually, bookmark menu items are
-// created dynamically. They also have a target of
-// BookmarkMenuCocoaController instead of firstResponder.
-// See BookmarkMenuBridge::AddNodeToMenu()).
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
-#pragma once
-
-#include <map>
-
-#include "base/scoped_nsobject.h"
-#include "chrome/browser/bookmarks/bookmark_model_observer.h"
-
-class BookmarkNode;
-class Profile;
-@class NSImage;
-@class NSMenu;
-@class NSMenuItem;
-@class BookmarkMenuCocoaController;
-
-class BookmarkMenuBridge : public BookmarkModelObserver {
- public:
- BookmarkMenuBridge(Profile* profile);
- virtual ~BookmarkMenuBridge();
-
- // Overridden from BookmarkModelObserver
- virtual void Loaded(BookmarkModel* model);
- virtual void BookmarkModelBeingDeleted(BookmarkModel* model);
- virtual void BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index);
- virtual void BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index);
- virtual void BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node);
- virtual void BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node);
- virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node);
- virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
- const BookmarkNode* node);
-
- // Rebuilds the bookmark menu, if it has been marked invalid.
- void UpdateMenu(NSMenu* bookmark_menu);
-
- // I wish I had a "friend @class" construct.
- BookmarkModel* GetBookmarkModel();
- Profile* GetProfile();
-
- protected:
- // Clear all bookmarks from the given bookmark menu.
- void ClearBookmarkMenu(NSMenu* menu);
-
- // Mark the bookmark menu as being invalid.
- void InvalidateMenu() { menuIsValid_ = false; }
-
- // Helper for adding the node as a submenu to the menu with the
- // given title.
- void AddNodeAsSubmenu(NSMenu* menu,
- const BookmarkNode* node,
- NSString* title);
-
- // Helper for recursively adding items to our bookmark menu
- // All children of |node| will be added to |menu|.
- // TODO(jrg): add a counter to enforce maximum nodes added
- void AddNodeToMenu(const BookmarkNode* node, NSMenu* menu);
-
- // This configures an NSMenuItem with all the data from a BookmarkNode. This
- // is used to update existing menu items, as well as to configure newly
- // created ones, like in AddNodeToMenu().
- // |set_title| is optional since it is only needed when we get a
- // node changed notification. On initial build of the menu we set
- // the title as part of alloc/init.
- void ConfigureMenuItem(const BookmarkNode* node, NSMenuItem* item,
- bool set_title);
-
- // Returns the NSMenuItem for a given BookmarkNode.
- NSMenuItem* MenuItemForNode(const BookmarkNode* node);
-
- // Return the Bookmark menu.
- virtual NSMenu* BookmarkMenu();
-
- // Start watching the bookmarks for changes.
- void ObserveBookmarkModel();
-
- private:
- friend class BookmarkMenuBridgeTest;
-
- // True iff the menu is up-to-date with the actual BookmarkModel.
- bool menuIsValid_;
-
- Profile* profile_; // weak
- BookmarkMenuCocoaController* controller_; // strong
-
- // The folder image so we can use one copy for all.
- scoped_nsobject<NSImage> folder_image_;
-
- // In order to appropriately update items in the bookmark menu, without
- // forcing a rebuild, map the model's nodes to menu items.
- std::map<const BookmarkNode*, NSMenuItem*> bookmark_nodes_;
-};
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.mm
deleted file mode 100644
index 7145285..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.mm
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <AppKit/AppKit.h>
-
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "base/nsimage_cache_mac.h"
-#include "base/sys_string_conversions.h"
-#import "chrome/browser/app_controller_mac.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/profile_manager.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "skia/ext/skia_utils_mac.h"
-
-BookmarkMenuBridge::BookmarkMenuBridge(Profile* profile)
- : menuIsValid_(false),
- profile_(profile),
- controller_([[BookmarkMenuCocoaController alloc] initWithBridge:this]) {
- if (GetBookmarkModel())
- ObserveBookmarkModel();
-}
-
-BookmarkMenuBridge::~BookmarkMenuBridge() {
- BookmarkModel *model = GetBookmarkModel();
- if (model)
- model->RemoveObserver(this);
- [controller_ release];
-}
-
-NSMenu* BookmarkMenuBridge::BookmarkMenu() {
- return [controller_ menu];
-}
-
-void BookmarkMenuBridge::Loaded(BookmarkModel* model) {
- InvalidateMenu();
-}
-
-void BookmarkMenuBridge::UpdateMenu(NSMenu* bookmark_menu) {
- DCHECK(bookmark_menu);
- if (menuIsValid_)
- return;
- BookmarkModel* model = GetBookmarkModel();
- if (!model || !model->IsLoaded())
- return;
-
- if (!folder_image_) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- folder_image_.reset(
- [rb.GetNativeImageNamed(IDR_BOOKMARK_BAR_FOLDER) retain]);
- }
-
- ClearBookmarkMenu(bookmark_menu);
-
- // Add bookmark bar items, if any.
- const BookmarkNode* barNode = model->GetBookmarkBarNode();
- CHECK(barNode);
- if (barNode->GetChildCount()) {
- [bookmark_menu addItem:[NSMenuItem separatorItem]];
- AddNodeToMenu(barNode, bookmark_menu);
- }
-
- // Create a submenu for "other bookmarks", and fill it in.
- NSString* other_items_title =
- l10n_util::GetNSString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME);
- [bookmark_menu addItem:[NSMenuItem separatorItem]];
- AddNodeAsSubmenu(bookmark_menu,
- model->other_node(),
- other_items_title);
-
- menuIsValid_ = true;
-}
-
-void BookmarkMenuBridge::BookmarkModelBeingDeleted(BookmarkModel* model) {
- NSMenu* bookmark_menu = BookmarkMenu();
- if (bookmark_menu == nil)
- return;
-
- ClearBookmarkMenu(bookmark_menu);
-}
-
-void BookmarkMenuBridge::BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index) {
- InvalidateMenu();
-}
-
-void BookmarkMenuBridge::BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index) {
- InvalidateMenu();
-}
-
-void BookmarkMenuBridge::BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node) {
- InvalidateMenu();
-}
-
-void BookmarkMenuBridge::BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node) {
- NSMenuItem* item = MenuItemForNode(node);
- if (item)
- ConfigureMenuItem(node, item, true);
-}
-
-void BookmarkMenuBridge::BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node) {
- NSMenuItem* item = MenuItemForNode(node);
- if (item)
- ConfigureMenuItem(node, item, false);
-}
-
-void BookmarkMenuBridge::BookmarkNodeChildrenReordered(
- BookmarkModel* model, const BookmarkNode* node) {
- InvalidateMenu();
-}
-
-// Watch for changes.
-void BookmarkMenuBridge::ObserveBookmarkModel() {
- BookmarkModel* model = GetBookmarkModel();
- model->AddObserver(this);
- if (model->IsLoaded())
- Loaded(model);
-}
-
-BookmarkModel* BookmarkMenuBridge::GetBookmarkModel() {
- if (!profile_)
- return NULL;
- return profile_->GetBookmarkModel();
-}
-
-Profile* BookmarkMenuBridge::GetProfile() {
- return profile_;
-}
-
-void BookmarkMenuBridge::ClearBookmarkMenu(NSMenu* menu) {
- bookmark_nodes_.clear();
- // Recursively delete all menus that look like a bookmark. Assume
- // all items with submenus contain only bookmarks. Also delete all
- // separator items since we explicirly add them back in. This should
- // deletes everything except the first item ("Add Bookmark...").
- NSArray* items = [menu itemArray];
- for (NSMenuItem* item in items) {
- // Convention: items in the bookmark list which are bookmarks have
- // an action of openBookmarkMenuItem:. Also, assume all items
- // with submenus are submenus of bookmarks.
- if (([item action] == @selector(openBookmarkMenuItem:)) ||
- [item hasSubmenu] ||
- [item isSeparatorItem]) {
- // This will eventually [obj release] all its kids, if it has
- // any.
- [menu removeItem:item];
- } else {
- // Leave it alone.
- }
- }
-}
-
-void BookmarkMenuBridge::AddNodeAsSubmenu(NSMenu* menu,
- const BookmarkNode* node,
- NSString* title) {
- NSMenuItem* items = [[[NSMenuItem alloc]
- initWithTitle:title
- action:nil
- keyEquivalent:@""] autorelease];
- [items setImage:folder_image_];
- [menu addItem:items];
- NSMenu* other_submenu = [[[NSMenu alloc] initWithTitle:title]
- autorelease];
- [menu setSubmenu:other_submenu forItem:items];
- AddNodeToMenu(node, other_submenu);
-}
-
-// TODO(jrg): limit the number of bookmarks in the menubar?
-void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu) {
- int child_count = node->GetChildCount();
- if (!child_count) {
- NSString* empty_string = l10n_util::GetNSString(IDS_MENU_EMPTY_SUBMENU);
- NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:empty_string
- action:nil
- keyEquivalent:@""] autorelease];
- [menu addItem:item];
- } else for (int i = 0; i < child_count; i++) {
- const BookmarkNode* child = node->GetChild(i);
- NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child];
- NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title
- action:nil
- keyEquivalent:@""] autorelease];
- [menu addItem:item];
- bookmark_nodes_[child] = item;
- if (child->is_folder()) {
- [item setImage:folder_image_];
- NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease];
- [menu setSubmenu:submenu forItem:item];
- AddNodeToMenu(child, submenu); // recursive call
- } else {
- ConfigureMenuItem(child, item, false);
- }
- }
-}
-
-void BookmarkMenuBridge::ConfigureMenuItem(const BookmarkNode* node,
- NSMenuItem* item,
- bool set_title) {
- if (set_title) {
- NSString* title = [BookmarkMenuCocoaController menuTitleForNode:node];
- [item setTitle:title];
- }
- [item setTarget:controller_];
- [item setAction:@selector(openBookmarkMenuItem:)];
- [item setTag:node->id()];
- // Add a tooltip
- std::string url_string = node->GetURL().possibly_invalid_spec();
- NSString* tooltip = [NSString stringWithFormat:@"%@\n%s",
- base::SysUTF16ToNSString(node->GetTitle()),
- url_string.c_str()];
- [item setToolTip:tooltip];
-
- // Check to see if we have a favicon.
- NSImage* favicon = nil;
- BookmarkModel* model = GetBookmarkModel();
- if (model) {
- const SkBitmap& bitmap = model->GetFavIcon(node);
- if (!bitmap.isNull())
- favicon = gfx::SkBitmapToNSImage(bitmap);
- }
- // Either we do not have a loaded favicon or the conversion from SkBitmap
- // failed. Use the default site image instead.
- if (!favicon)
- favicon = nsimage_cache::ImageNamed(@"nav.pdf");
- [item setImage:favicon];
-}
-
-NSMenuItem* BookmarkMenuBridge::MenuItemForNode(const BookmarkNode* node) {
- if (!node)
- return nil;
- std::map<const BookmarkNode*, NSMenuItem*>::iterator it =
- bookmark_nodes_.find(node);
- if (it == bookmark_nodes_.end())
- return nil;
- return it->second;
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm
deleted file mode 100644
index 5f06ce5..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <AppKit/AppKit.h>
-
-#import "base/scoped_nsobject.h"
-#include "base/string16.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#include "chrome/browser/ui/browser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-class TestBookmarkMenuBridge : public BookmarkMenuBridge {
- public:
- TestBookmarkMenuBridge(Profile* profile)
- : BookmarkMenuBridge(profile),
- menu_([[NSMenu alloc] initWithTitle:@"test"]) {
- }
- virtual ~TestBookmarkMenuBridge() {}
-
- scoped_nsobject<NSMenu> menu_;
-
- protected:
- // Overridden from BookmarkMenuBridge.
- virtual NSMenu* BookmarkMenu() {
- return menu_;
- }
-};
-
-// TODO(jrg): see refactor comment in bookmark_bar_state_controller_unittest.mm
-class BookmarkMenuBridgeTest : public PlatformTest {
- public:
-
- void SetUp() {
- bridge_.reset(new TestBookmarkMenuBridge(browser_test_helper_.profile()));
- EXPECT_TRUE(bridge_.get());
- }
-
- // We are a friend of BookmarkMenuBridge (and have access to
- // protected methods), but none of the classes generated by TEST_F()
- // are. This (and AddNodeToMenu()) are simple wrappers to let
- // derived test classes have access to protected methods.
- void ClearBookmarkMenu(BookmarkMenuBridge* bridge, NSMenu* menu) {
- bridge->ClearBookmarkMenu(menu);
- }
-
- void InvalidateMenu() { bridge_->InvalidateMenu(); }
- bool menu_is_valid() { return bridge_->menuIsValid_; }
-
- void AddNodeToMenu(BookmarkMenuBridge* bridge, const BookmarkNode* root,
- NSMenu* menu) {
- bridge->AddNodeToMenu(root, menu);
- }
-
- NSMenuItem* MenuItemForNode(BookmarkMenuBridge* bridge,
- const BookmarkNode* node) {
- return bridge->MenuItemForNode(node);
- }
-
- NSMenuItem* AddItemToMenu(NSMenu *menu, NSString *title, SEL selector) {
- NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:title action:NULL
- keyEquivalent:@""] autorelease];
- if (selector)
- [item setAction:selector];
- [menu addItem:item];
- return item;
- }
-
- BrowserTestHelper browser_test_helper_;
- scoped_ptr<TestBookmarkMenuBridge> bridge_;
-};
-
-TEST_F(BookmarkMenuBridgeTest, TestBookmarkMenuAutoSeparator) {
- BookmarkModel* model = bridge_->GetBookmarkModel();
- bridge_->Loaded(model);
- NSMenu* menu = bridge_->menu_.get();
- bridge_->UpdateMenu(menu);
- // The bare menu after loading has a separator and an "Other Bookmarks"
- // submenu.
- EXPECT_EQ(2, [menu numberOfItems]);
- // Add a bookmark and reload and there should be 4 items: the previous
- // menu contents plus a new separator and the new bookmark.
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const char* url = "http://www.zim-bop-a-dee.com/";
- model->AddURL(parent, 0, ASCIIToUTF16("Bookmark"), GURL(url));
- bridge_->UpdateMenu(menu);
- EXPECT_EQ(4, [menu numberOfItems]);
- // Remove the new bookmark and reload and we should have 2 items again
- // because the separator should have been removed as well.
- model->Remove(parent, 0);
- bridge_->UpdateMenu(menu);
- EXPECT_EQ(2, [menu numberOfItems]);
-}
-
-// Test that ClearBookmarkMenu() removes all bookmark menus.
-TEST_F(BookmarkMenuBridgeTest, TestClearBookmarkMenu) {
- NSMenu* menu = bridge_->menu_.get();
-
- AddItemToMenu(menu, @"hi mom", nil);
- AddItemToMenu(menu, @"not", @selector(openBookmarkMenuItem:));
- NSMenuItem* item = AddItemToMenu(menu, @"hi mom", nil);
- [item setSubmenu:[[[NSMenu alloc] initWithTitle:@"bar"] autorelease]];
- AddItemToMenu(menu, @"not", @selector(openBookmarkMenuItem:));
- AddItemToMenu(menu, @"zippy", @selector(length));
- [menu addItem:[NSMenuItem separatorItem]];
-
- ClearBookmarkMenu(bridge_.get(), menu);
-
- // Make sure all bookmark items are removed, all items with
- // submenus removed, and all separator items are gone.
- EXPECT_EQ(2, [menu numberOfItems]);
- for (NSMenuItem *item in [menu itemArray]) {
- EXPECT_NSNE(@"not", [item title]);
- }
-}
-
-// Test invalidation
-TEST_F(BookmarkMenuBridgeTest, TestInvalidation) {
- BookmarkModel* model = bridge_->GetBookmarkModel();
- bridge_->Loaded(model);
-
- EXPECT_FALSE(menu_is_valid());
- bridge_->UpdateMenu(bridge_->menu_);
- EXPECT_TRUE(menu_is_valid());
-
- InvalidateMenu();
- EXPECT_FALSE(menu_is_valid());
- InvalidateMenu();
- EXPECT_FALSE(menu_is_valid());
- bridge_->UpdateMenu(bridge_->menu_);
- EXPECT_TRUE(menu_is_valid());
- bridge_->UpdateMenu(bridge_->menu_);
- EXPECT_TRUE(menu_is_valid());
-
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const char* url = "http://www.zim-bop-a-dee.com/";
- model->AddURL(parent, 0, ASCIIToUTF16("Bookmark"), GURL(url));
-
- EXPECT_FALSE(menu_is_valid());
- bridge_->UpdateMenu(bridge_->menu_);
- EXPECT_TRUE(menu_is_valid());
-}
-
-// Test that AddNodeToMenu() properly adds bookmark nodes as menus,
-// including the recursive case.
-TEST_F(BookmarkMenuBridgeTest, TestAddNodeToMenu) {
- string16 empty;
- NSMenu* menu = bridge_->menu_.get();
-
- BookmarkModel* model = bridge_->GetBookmarkModel();
- const BookmarkNode* root = model->GetBookmarkBarNode();
- EXPECT_TRUE(model && root);
-
- const char* short_url = "http://foo/";
- const char* long_url = "http://super-duper-long-url--."
- "that.cannot.possibly.fit.even-in-80-columns"
- "or.be.reasonably-displayed-in-a-menu"
- "without.looking-ridiculous.com/"; // 140 chars total
-
- // 3 nodes; middle one has a child, last one has a HUGE URL
- // Set their titles to be the same as the URLs
- const BookmarkNode* node = NULL;
- model->AddURL(root, 0, ASCIIToUTF16(short_url), GURL(short_url));
- bridge_->UpdateMenu(menu);
- int prev_count = [menu numberOfItems] - 1; // "extras" added at this point
- node = model->AddGroup(root, 1, empty);
- model->AddURL(root, 2, ASCIIToUTF16(long_url), GURL(long_url));
-
- // And the submenu fo the middle one
- model->AddURL(node, 0, empty, GURL("http://sub"));
- bridge_->UpdateMenu(menu);
-
- EXPECT_EQ((NSInteger)(prev_count+3), [menu numberOfItems]);
-
- // Verify the 1st one is there with the right action.
- NSMenuItem* item = [menu itemWithTitle:[NSString
- stringWithUTF8String:short_url]];
- EXPECT_TRUE(item);
- EXPECT_EQ(@selector(openBookmarkMenuItem:), [item action]);
- EXPECT_EQ(NO, [item hasSubmenu]);
- NSMenuItem* short_item = item;
- NSMenuItem* long_item = nil;
-
- // Now confirm we have 2 submenus (the one we added, plus "other")
- int subs = 0;
- for (item in [menu itemArray]) {
- if ([item hasSubmenu])
- subs++;
- }
- EXPECT_EQ(2, subs);
-
- for (item in [menu itemArray]) {
- if ([[item title] hasPrefix:@"http://super-duper"]) {
- long_item = item;
- break;
- }
- }
- EXPECT_TRUE(long_item);
-
- // Make sure a short title looks fine
- NSString* s = [short_item title];
- EXPECT_NSEQ([NSString stringWithUTF8String:short_url], s);
-
- // Make sure a super-long title gets trimmed
- s = [long_item title];
- EXPECT_TRUE([s length] < strlen(long_url));
-
- // Confirm tooltips and confirm they are not trimmed (like the item
- // name might be). Add tolerance for URL fixer-upping;
- // e.g. http://foo becomes http://foo/)
- EXPECT_GE([[short_item toolTip] length], (2*strlen(short_url) - 5));
- EXPECT_GE([[long_item toolTip] length], (2*strlen(long_url) - 5));
-
- // Make sure the favicon is non-nil (should be either the default site
- // icon or a favicon, if present).
- EXPECT_TRUE([short_item image]);
- EXPECT_TRUE([long_item image]);
-}
-
-// Makes sure our internal map of BookmarkNode to NSMenuItem works.
-TEST_F(BookmarkMenuBridgeTest, TestGetMenuItemForNode) {
- string16 empty;
- NSMenu* menu = bridge_->menu_.get();
-
- BookmarkModel* model = bridge_->GetBookmarkModel();
- const BookmarkNode* bookmark_bar = model->GetBookmarkBarNode();
- const BookmarkNode* root = model->AddGroup(bookmark_bar, 0, empty);
- EXPECT_TRUE(model && root);
-
- model->AddURL(root, 0, ASCIIToUTF16("Test Item"), GURL("http://test"));
- AddNodeToMenu(bridge_.get(), root, menu);
- EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(0)));
-
- model->AddURL(root, 1, ASCIIToUTF16("Test 2"), GURL("http://second-test"));
- AddNodeToMenu(bridge_.get(), root, menu);
- EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(0)));
- EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(1)));
-
- const BookmarkNode* removed_node = root->GetChild(0);
- EXPECT_EQ(2, root->GetChildCount());
- model->Remove(root, 0);
- EXPECT_EQ(1, root->GetChildCount());
- bridge_->UpdateMenu(menu);
- EXPECT_FALSE(MenuItemForNode(bridge_.get(), removed_node));
- EXPECT_TRUE(MenuItemForNode(bridge_.get(), root->GetChild(0)));
-
- const BookmarkNode empty_node(GURL("http://no-where/"));
- EXPECT_FALSE(MenuItemForNode(bridge_.get(), &empty_node));
- EXPECT_FALSE(MenuItemForNode(bridge_.get(), NULL));
-}
-
-// Test that Loaded() adds both the bookmark bar nodes and the "other" nodes.
-TEST_F(BookmarkMenuBridgeTest, TestAddNodeToOther) {
- NSMenu* menu = bridge_->menu_.get();
-
- BookmarkModel* model = bridge_->GetBookmarkModel();
- const BookmarkNode* root = model->other_node();
- EXPECT_TRUE(model && root);
-
- const char* short_url = "http://foo/";
- model->AddURL(root, 0, ASCIIToUTF16(short_url), GURL(short_url));
-
- bridge_->UpdateMenu(menu);
- ASSERT_GT([menu numberOfItems], 0);
- NSMenuItem* other = [menu itemAtIndex:([menu numberOfItems]-1)];
- EXPECT_TRUE(other);
- EXPECT_TRUE([other hasSubmenu]);
- ASSERT_GT([[other submenu] numberOfItems], 0);
- EXPECT_NSEQ(@"http://foo/", [[[other submenu] itemAtIndex:0] title]);
-}
-
-TEST_F(BookmarkMenuBridgeTest, TestFavIconLoading) {
- NSMenu* menu = bridge_->menu_;
-
- BookmarkModel* model = bridge_->GetBookmarkModel();
- const BookmarkNode* root = model->GetBookmarkBarNode();
- EXPECT_TRUE(model && root);
-
- const BookmarkNode* node =
- model->AddURL(root, 0, ASCIIToUTF16("Test Item"),
- GURL("http://favicon-test"));
- bridge_->UpdateMenu(menu);
- NSMenuItem* item = [menu itemWithTitle:@"Test Item"];
- EXPECT_TRUE([item image]);
- [item setImage:nil];
- bridge_->BookmarkNodeFavIconLoaded(model, node);
- EXPECT_TRUE([item image]);
-}
-
-TEST_F(BookmarkMenuBridgeTest, TestChangeTitle) {
- NSMenu* menu = bridge_->menu_;
- BookmarkModel* model = bridge_->GetBookmarkModel();
- const BookmarkNode* root = model->GetBookmarkBarNode();
- EXPECT_TRUE(model && root);
-
- const BookmarkNode* node =
- model->AddURL(root, 0, ASCIIToUTF16("Test Item"),
- GURL("http://title-test"));
- bridge_->UpdateMenu(menu);
- NSMenuItem* item = [menu itemWithTitle:@"Test Item"];
- EXPECT_TRUE([item image]);
-
- model->SetTitle(node, ASCIIToUTF16("New Title"));
-
- item = [menu itemWithTitle:@"Test Item"];
- EXPECT_FALSE(item);
- item = [menu itemWithTitle:@"New Title"];
- EXPECT_TRUE(item);
-}
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h
deleted file mode 100644
index dc5c221..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2010 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.
-
-// Controller (MVC) for the bookmark menu.
-// All bookmark menu item commands get directed here.
-// Unfortunately there is already a C++ class named BookmarkMenuController.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_COCOA_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_COCOA_CONTROLLER_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#import "base/cocoa_protocols_mac.h"
-
-class BookmarkNode;
-class BookmarkMenuBridge;
-
-@interface BookmarkMenuCocoaController : NSObject<NSMenuDelegate> {
- @private
- BookmarkMenuBridge* bridge_; // weak; owns me
-}
-
-// The Bookmarks menu
-@property (nonatomic, readonly) NSMenu* menu;
-
-// Return an autoreleased string to be used as a menu title for the
-// given bookmark node.
-+ (NSString*)menuTitleForNode:(const BookmarkNode*)node;
-
-- (id)initWithBridge:(BookmarkMenuBridge *)bridge;
-
-// Called by any Bookmark menu item.
-// The menu item's tag is the bookmark ID.
-- (IBAction)openBookmarkMenuItem:(id)sender;
-
-@end // BookmarkMenuCocoaController
-
-
-@interface BookmarkMenuCocoaController (ExposedForUnitTests)
-- (const BookmarkNode*)nodeForIdentifier:(int)identifier;
-- (void)openURLForNode:(const BookmarkNode*)node;
-@end // BookmarkMenuCocoaController (ExposedForUnitTests)
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MENU_COCOA_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm
deleted file mode 100644
index 93ff846..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
-
-#include "app/text_elider.h"
-#include "base/sys_string_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/app/chrome_command_ids.h" // IDC_BOOKMARK_MENU
-#import "chrome/browser/app_controller_mac.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h"
-#include "chrome/browser/cocoa/event_utils.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/ui/browser.h"
-#include "webkit/glue/window_open_disposition.h"
-
-namespace {
-
-// Menus more than this many pixels wide will get trimmed
-// TODO(jrg): ask UI dudes what a good value is.
-const NSUInteger kMaximumMenuPixelsWide = 300;
-
-}
-
-@implementation BookmarkMenuCocoaController
-
-+ (NSString*)menuTitleForNode:(const BookmarkNode*)node {
- NSFont* nsfont = [NSFont menuBarFontOfSize:0]; // 0 means "default"
- gfx::Font font(base::SysNSStringToWide([nsfont fontName]),
- static_cast<int>([nsfont pointSize]));
- string16 title = gfx::ElideText(node->GetTitle(),
- font,
- kMaximumMenuPixelsWide,
- false);
- return base::SysUTF16ToNSString(title);
-}
-
-- (id)initWithBridge:(BookmarkMenuBridge *)bridge {
- if ((self = [super init])) {
- bridge_ = bridge;
- DCHECK(bridge_);
- [[self menu] setDelegate:self];
- }
- return self;
-}
-
-- (void)dealloc {
- [[self menu] setDelegate:nil];
- [super dealloc];
-}
-
-- (NSMenu*)menu {
- return [[[NSApp mainMenu] itemWithTag:IDC_BOOKMARK_MENU] submenu];
-}
-
-- (BOOL)validateMenuItem:(NSMenuItem*)menuItem {
- AppController* controller = [NSApp delegate];
- return [controller keyWindowIsNotModal];
-}
-
-// NSMenu delegate method: called just before menu is displayed.
-- (void)menuNeedsUpdate:(NSMenu*)menu {
- bridge_->UpdateMenu(menu);
-}
-
-// Return the a BookmarkNode that has the given id (called
-// "identifier" here to avoid conflict with objc's concept of "id").
-- (const BookmarkNode*)nodeForIdentifier:(int)identifier {
- return bridge_->GetBookmarkModel()->GetNodeByID(identifier);
-}
-
-// Open the URL of the given BookmarkNode in the current tab.
-- (void)openURLForNode:(const BookmarkNode*)node {
- Browser* browser = Browser::GetTabbedBrowser(bridge_->GetProfile(), true);
- if (!browser)
- browser = Browser::Create(bridge_->GetProfile());
- WindowOpenDisposition disposition =
- event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
- browser->OpenURL(node->GetURL(), GURL(), disposition,
- PageTransition::AUTO_BOOKMARK);
-}
-
-- (IBAction)openBookmarkMenuItem:(id)sender {
- NSInteger tag = [sender tag];
- int identifier = tag;
- const BookmarkNode* node = [self nodeForIdentifier:identifier];
- DCHECK(node);
- if (!node)
- return; // shouldn't be reached
-
- [self openURLForNode:node];
-}
-
-@end // BookmarkMenuCocoaController
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm
deleted file mode 100644
index 8c0b4cd..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "base/string16.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
-#include "chrome/browser/ui/browser.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-@interface FakeBookmarkMenuController : BookmarkMenuCocoaController {
- @public
- BrowserTestHelper* helper_;
- const BookmarkNode* nodes_[2];
- BOOL opened_[2];
-}
-@end
-
-@implementation FakeBookmarkMenuController
-
-- (id)init {
- if ((self = [super init])) {
- string16 empty;
- helper_ = new BrowserTestHelper();
- BookmarkModel* model = helper_->browser()->profile()->GetBookmarkModel();
- const BookmarkNode* bookmark_bar = model->GetBookmarkBarNode();
- nodes_[0] = model->AddURL(bookmark_bar, 0, empty, GURL("http://0.com"));
- nodes_[1] = model->AddURL(bookmark_bar, 1, empty, GURL("http://1.com"));
- }
- return self;
-}
-
-- (void)dealloc {
- delete helper_;
- [super dealloc];
-}
-
-- (const BookmarkNode*)nodeForIdentifier:(int)identifier {
- if ((identifier < 0) || (identifier >= 2))
- return NULL;
- return nodes_[identifier];
-}
-
-- (void)openURLForNode:(const BookmarkNode*)node {
- std::string url = node->GetURL().possibly_invalid_spec();
- if (url.find("http://0.com") != std::string::npos)
- opened_[0] = YES;
- if (url.find("http://1.com") != std::string::npos)
- opened_[1] = YES;
-}
-
-@end // FakeBookmarkMenuController
-
-
-TEST(BookmarkMenuCocoaControllerTest, TestOpenItem) {
- FakeBookmarkMenuController *c = [[FakeBookmarkMenuController alloc] init];
- NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
- for (int i = 0; i < 2; i++) {
- [item setTag:i];
- ASSERT_EQ(c->opened_[i], NO);
- [c openBookmarkMenuItem:item];
- ASSERT_NE(c->opened_[i], NO);
- }
- [c release];
-}
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_unittest.mm
deleted file mode 100644
index bed4f55..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_menu_unittest.mm
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/scoped_nsobject.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_menu.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-namespace {
-
-class BookmarkMenuTest : public CocoaTest {
-};
-
-TEST_F(BookmarkMenuTest, Basics) {
- scoped_nsobject<BookmarkMenu> menu([[BookmarkMenu alloc]
- initWithTitle:@"title"]);
- scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] initWithTitle:@"item"
- action:NULL
- keyEquivalent:@""]);
- [menu addItem:item];
- long long l = 103849459459598948LL; // arbitrary
- NSNumber* number = [NSNumber numberWithLongLong:l];
- [menu setRepresentedObject:number];
- EXPECT_EQ(l, [menu id]);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h b/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
deleted file mode 100644
index 4acc972..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2010 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.
-
-// C++ bridge class to send a selector to a Cocoa object when the
-// bookmark model changes. Some Cocoa objects edit the bookmark model
-// and temporarily save a copy of the state (e.g. bookmark button
-// editor). As a fail-safe, these objects want an easy cancel if the
-// model changes out from under them. For example, if you have the
-// bookmark button editor sheet open, then edit the bookmark in the
-// bookmark manager, we'd want to simply cancel the editor.
-//
-// This class is conservative and may result in notifications which
-// aren't strictly necessary. For example, node removal only needs to
-// cancel an edit if the removed node is a folder (editors often have
-// a list of "new parents"). But, just to be sure, notification
-// happens on any removal.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MODEL_OBSERVER_FOR_COCOA_H
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MODEL_OBSERVER_FOR_COCOA_H
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/basictypes.h"
-#include "base/scoped_nsobject.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_model_observer.h"
-
-class BookmarkModelObserverForCocoa : public BookmarkModelObserver {
- public:
- // When |node| in |model| changes, send |selector| to |object|.
- // Assumes |selector| is a selector that takes one arg, like an
- // IBOutlet. The arg passed is nil.
- // Many notifications happen independently of node
- // (e.g. BeingDeleted), so |node| can be nil.
- //
- // |object| is NOT retained, since the expected use case is for
- // ||object| to own the BookmarkModelObserverForCocoa and we don't
- // want a retain cycle.
- BookmarkModelObserverForCocoa(const BookmarkNode* node,
- BookmarkModel* model,
- NSObject* object,
- SEL selector) {
- DCHECK(model);
- node_ = node;
- model_ = model;
- object_ = object;
- selector_ = selector;
- model_->AddObserver(this);
- }
- virtual ~BookmarkModelObserverForCocoa() {
- model_->RemoveObserver(this);
- }
-
- virtual void BookmarkModelBeingDeleted(BookmarkModel* model) {
- Notify();
- }
- virtual void BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- int old_index,
- const BookmarkNode* new_parent,
- int new_index) {
- // Editors often have a tree of parents, so movement of folders
- // must cause a cancel.
- Notify();
- }
- virtual void BookmarkNodeRemoved(BookmarkModel* model,
- const BookmarkNode* parent,
- int old_index,
- const BookmarkNode* node) {
- // See comment in BookmarkNodeMoved.
- Notify();
- }
- virtual void BookmarkNodeChanged(BookmarkModel* model,
- const BookmarkNode* node) {
- if ((node_ == node) || (!node_))
- Notify();
- }
- virtual void BookmarkImportBeginning(BookmarkModel* model) {
- // Be conservative.
- Notify();
- }
-
- // Some notifications we don't care about, but by being pure virtual
- // in the base class we must implement them.
- virtual void Loaded(BookmarkModel* model) {
- }
- virtual void BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- int index) {
- }
- virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
- const BookmarkNode* node) {
- }
- virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
- const BookmarkNode* node) {
- }
-
- virtual void BookmarkImportEnding(BookmarkModel* model) {
- }
-
- private:
- const BookmarkNode* node_; // Weak; owned by a BookmarkModel.
- BookmarkModel* model_; // Weak; it is owned by a Profile.
- NSObject* object_; // Weak, like a delegate.
- SEL selector_;
-
- void Notify() {
- [object_ performSelector:selector_ withObject:nil];
- }
-
- DISALLOW_COPY_AND_ASSIGN(BookmarkModelObserverForCocoa);
-};
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_MODEL_OBSERVER_FOR_COCOA_H
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm
deleted file mode 100644
index a84cc53..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa_unittest.mm
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_ptr.h"
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h"
-#import "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-
-// Keep track of bookmark pings.
-@interface ObserverPingTracker : NSObject {
- @public
- int pings;
-}
-@end
-
-@implementation ObserverPingTracker
-- (void)pingMe:(id)sender {
- pings++;
-}
-@end
-
-namespace {
-
-class BookmarkModelObserverForCocoaTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
-
- BookmarkModelObserverForCocoaTest() {}
- virtual ~BookmarkModelObserverForCocoaTest() {}
- private:
- DISALLOW_COPY_AND_ASSIGN(BookmarkModelObserverForCocoaTest);
-};
-
-
-TEST_F(BookmarkModelObserverForCocoaTest, TestCallback) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* node = model->AddURL(model->GetBookmarkBarNode(),
- 0, ASCIIToUTF16("super"),
- GURL("http://www.google.com"));
-
- scoped_nsobject<ObserverPingTracker>
- pingCount([[ObserverPingTracker alloc] init]);
-
- scoped_ptr<BookmarkModelObserverForCocoa>
- observer(new BookmarkModelObserverForCocoa(node, model,
- pingCount,
- @selector(pingMe:)));
-
- EXPECT_EQ(0, pingCount.get()->pings);
-
- model->SetTitle(node, ASCIIToUTF16("duper"));
- EXPECT_EQ(1, pingCount.get()->pings);
- model->SetURL(node, GURL("http://www.google.com/reader"));
- EXPECT_EQ(2, pingCount.get()->pings);
-
- model->Move(node, model->other_node(), 0);
- EXPECT_EQ(3, pingCount.get()->pings);
-
- model->Remove(node->GetParent(), 0);
- EXPECT_EQ(4, pingCount.get()->pings);
-}
-
-} // namespace
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h
deleted file mode 100644
index 7de139f..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_NAME_FOLDER_CONTROLLER_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_NAME_FOLDER_CONTROLLER_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_nsobject.h"
-#include "base/scoped_ptr.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-
-class BookmarkModelObserverForCocoa;
-
-// A controller for dialog to let the user create a new folder or
-// rename an existing folder. Accessible from a context menu on a
-// bookmark button or the bookmark bar.
-@interface BookmarkNameFolderController : NSWindowController {
- @private
- IBOutlet NSTextField* nameField_;
- IBOutlet NSButton* okButton_;
-
- NSWindow* parentWindow_; // weak
- Profile* profile_; // weak
-
- // Weak; owned by the model. Can be NULL (see below). Either node_
- // is non-NULL (renaming a folder), or parent_ is non-NULL (adding a
- // new one).
- const BookmarkNode* node_;
- const BookmarkNode* parent_;
- int newIndex_;
-
- scoped_nsobject<NSString> initialName_;
-
- // Ping me when things change out from under us.
- scoped_ptr<BookmarkModelObserverForCocoa> observer_;
-}
-
-// Use the 1st initializer for a "rename existing folder" request.
-//
-// Use the 2nd initializer for an "add folder" request. If creating a
-// new folder |parent| and |newIndex| specify where to put the new
-// node.
-- (id)initWithParentWindow:(NSWindow*)window
- profile:(Profile*)profile
- node:(const BookmarkNode*)node;
-- (id)initWithParentWindow:(NSWindow*)window
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- newIndex:(int)newIndex;
-- (void)runAsModalSheet;
-- (IBAction)cancel:(id)sender;
-- (IBAction)ok:(id)sender;
-@end
-
-@interface BookmarkNameFolderController(TestingAPI)
-- (NSString*)folderName;
-- (void)setFolderName:(NSString*)name;
-- (NSButton*)okButton;
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_NAME_FOLDER_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.mm
deleted file mode 100644
index fe8cdfd..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.mm
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h"
-
-#include "app/l10n_util.h"
-#include "app/l10n_util_mac.h"
-#include "base/mac_util.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/cocoa/bookmarks/bookmark_model_observer_for_cocoa.h"
-#include "chrome/browser/profile.h"
-#include "grit/generated_resources.h"
-
-@implementation BookmarkNameFolderController
-
-// Common initializer (private).
-- (id)initWithParentWindow:(NSWindow*)window
- profile:(Profile*)profile
- node:(const BookmarkNode*)node
- parent:(const BookmarkNode*)parent
- newIndex:(int)newIndex {
- NSString* nibpath = [mac_util::MainAppBundle()
- pathForResource:@"BookmarkNameFolder"
- ofType:@"nib"];
- if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
- parentWindow_ = window;
- profile_ = profile;
- node_ = node;
- parent_ = parent;
- newIndex_ = newIndex;
- if (parent) {
- DCHECK_LE(newIndex, parent->GetChildCount());
- }
- if (node_) {
- initialName_.reset([base::SysUTF16ToNSString(node_->GetTitle()) retain]);
- } else {
- NSString* newString =
- l10n_util::GetNSStringWithFixup(IDS_BOOMARK_EDITOR_NEW_FOLDER_NAME);
- initialName_.reset([newString retain]);
- }
- }
- return self;
-}
-
-- (id)initWithParentWindow:(NSWindow*)window
- profile:(Profile*)profile
- node:(const BookmarkNode*)node {
- DCHECK(node);
- return [self initWithParentWindow:window
- profile:profile
- node:node
- parent:nil
- newIndex:0];
-}
-
-- (id)initWithParentWindow:(NSWindow*)window
- profile:(Profile*)profile
- parent:(const BookmarkNode*)parent
- newIndex:(int)newIndex {
- DCHECK(parent);
- return [self initWithParentWindow:window
- profile:profile
- node:nil
- parent:parent
- newIndex:newIndex];
-}
-
-- (void)awakeFromNib {
- [nameField_ setStringValue:initialName_.get()];
-}
-
-- (void)runAsModalSheet {
- // Ping me when things change out from under us.
- observer_.reset(new BookmarkModelObserverForCocoa(
- node_, profile_->GetBookmarkModel(),
- self,
- @selector(cancel:)));
- [NSApp beginSheet:[self window]
- modalForWindow:parentWindow_
- modalDelegate:self
- didEndSelector:@selector(didEndSheet:returnCode:contextInfo:)
- contextInfo:nil];
-}
-
-- (IBAction)cancel:(id)sender {
- [NSApp endSheet:[self window]];
-}
-
-- (IBAction)ok:(id)sender {
- NSString* name = [nameField_ stringValue];
- BookmarkModel* model = profile_->GetBookmarkModel();
- if (node_) {
- model->SetTitle(node_, base::SysNSStringToUTF16(name));
- } else {
- model->AddGroup(parent_,
- newIndex_,
- base::SysNSStringToUTF16(name));
- }
- [NSApp endSheet:[self window]];
-}
-
-- (void)didEndSheet:(NSWindow*)sheet
- returnCode:(int)returnCode
- contextInfo:(void*)contextInfo {
- [[self window] orderOut:self];
- observer_.reset(NULL);
- [self autorelease];
-}
-
-- (NSString*)folderName {
- return [nameField_ stringValue];
-}
-
-- (void)setFolderName:(NSString*)name {
- [nameField_ setStringValue:name];
-}
-
-- (NSButton*)okButton {
- return okButton_;
-}
-
-@end // BookmarkNameFolderController
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm
deleted file mode 100644
index 3a435f7..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller_unittest.mm
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_name_folder_controller.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-#include "testing/platform_test.h"
-
-class BookmarkNameFolderControllerTest : public CocoaTest {
- public:
- BrowserTestHelper helper_;
-};
-
-
-// Simple add of a node (at the end).
-TEST_F(BookmarkNameFolderControllerTest, AddNew) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- EXPECT_EQ(0, parent->GetChildCount());
-
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- newIndex:0]);
- [controller window]; // force nib load
-
- // Do nothing.
- [controller cancel:nil];
- EXPECT_EQ(0, parent->GetChildCount());
-
- // Change name then cancel.
- [controller setFolderName:@"Bozo"];
- [controller cancel:nil];
- EXPECT_EQ(0, parent->GetChildCount());
-
- // Add a new folder.
- [controller ok:nil];
- EXPECT_EQ(1, parent->GetChildCount());
- EXPECT_TRUE(parent->GetChild(0)->is_folder());
- EXPECT_EQ(ASCIIToUTF16("Bozo"), parent->GetChild(0)->GetTitle());
-}
-
-// Add new but specify a sibling.
-TEST_F(BookmarkNameFolderControllerTest, AddNewWithSibling) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
-
- // Add 2 nodes. We will place the new folder in the middle of these.
- model->AddURL(parent, 0, ASCIIToUTF16("title 1"),
- GURL("http://www.google.com"));
- model->AddURL(parent, 1, ASCIIToUTF16("title 3"),
- GURL("http://www.google.com"));
- EXPECT_EQ(2, parent->GetChildCount());
-
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- newIndex:1]);
- [controller window]; // force nib load
-
- // Add a new folder.
- [controller setFolderName:@"middle"];
- [controller ok:nil];
-
- // Confirm we now have 3, and that the new one is in the middle.
- EXPECT_EQ(3, parent->GetChildCount());
- EXPECT_TRUE(parent->GetChild(1)->is_folder());
- EXPECT_EQ(ASCIIToUTF16("middle"), parent->GetChild(1)->GetTitle());
-}
-
-// Make sure we are allowed to create a folder named "New Folder".
-TEST_F(BookmarkNameFolderControllerTest, AddNewDefaultName) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- EXPECT_EQ(0, parent->GetChildCount());
-
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- newIndex:0]);
-
- [controller window]; // force nib load
-
- // Click OK without changing the name
- [controller ok:nil];
- EXPECT_EQ(1, parent->GetChildCount());
- EXPECT_TRUE(parent->GetChild(0)->is_folder());
-}
-
-// Make sure we are allowed to create a folder with an empty name.
-TEST_F(BookmarkNameFolderControllerTest, AddNewBlankName) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- EXPECT_EQ(0, parent->GetChildCount());
-
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- newIndex:0]);
- [controller window]; // force nib load
-
- // Change the name to blank, click OK.
- [controller setFolderName:@""];
- [controller ok:nil];
- EXPECT_EQ(1, parent->GetChildCount());
- EXPECT_TRUE(parent->GetChild(0)->is_folder());
-}
-
-TEST_F(BookmarkNameFolderControllerTest, Rename) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- const BookmarkNode* folder = model->AddGroup(parent,
- parent->GetChildCount(),
- ASCIIToUTF16("group"));
-
- // Rename the folder by creating a controller that originates from
- // the node.
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- node:folder]);
- [controller window]; // force nib load
-
- EXPECT_NSEQ(@"group", [controller folderName]);
- [controller setFolderName:@"Zobo"];
- [controller ok:nil];
- EXPECT_EQ(1, parent->GetChildCount());
- EXPECT_TRUE(parent->GetChild(0)->is_folder());
- EXPECT_EQ(ASCIIToUTF16("Zobo"), parent->GetChild(0)->GetTitle());
-}
-
-TEST_F(BookmarkNameFolderControllerTest, EditAndConfirmOKButton) {
- BookmarkModel* model = helper_.profile()->GetBookmarkModel();
- const BookmarkNode* parent = model->GetBookmarkBarNode();
- EXPECT_EQ(0, parent->GetChildCount());
-
- scoped_nsobject<BookmarkNameFolderController>
- controller([[BookmarkNameFolderController alloc]
- initWithParentWindow:test_window()
- profile:helper_.profile()
- parent:parent
- newIndex:0]);
- [controller window]; // force nib load
-
- // We start enabled since the default "New Folder" is added for us.
- EXPECT_TRUE([[controller okButton] isEnabled]);
-
- [controller setFolderName:@"Bozo"];
- EXPECT_TRUE([[controller okButton] isEnabled]);
- [controller setFolderName:@" "];
- EXPECT_TRUE([[controller okButton] isEnabled]);
-
- [controller setFolderName:@""];
- EXPECT_TRUE([[controller okButton] isEnabled]);
-}
-
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h b/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h
deleted file mode 100644
index 7cdee51..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2010 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_COCOA_BOOKMARKS_BOOKMARK_TREE_BROWSER_CELL_H_
-#define CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_TREE_BROWSER_CELL_H_
-#pragma once
-
-#import <Cocoa/Cocoa.h>
-
-class BookmarkNode;
-
-// Provides a custom cell as used in the BookmarkEditor.xib's folder tree
-// browser view. This cell customization adds target and action support
-// not provided by the NSBrowserCell as well as contextual information
-// identifying the bookmark node being edited and the column matrix
-// control in which is contained the cell.
-@interface BookmarkTreeBrowserCell : NSBrowserCell {
- @private
- const BookmarkNode* bookmarkNode_; // weak
- NSMatrix* matrix_; // weak
- id target_; // weak
- SEL action_;
-}
-
-@property (nonatomic, assign) NSMatrix* matrix;
-@property (nonatomic, assign) id target;
-@property (nonatomic, assign) SEL action;
-
-- (const BookmarkNode*)bookmarkNode;
-- (void)setBookmarkNode:(const BookmarkNode*)bookmarkNode;
-
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARKS_BOOKMARK_TREE_BROWSER_CELL_H_
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.mm b/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.mm
deleted file mode 100644
index b778858..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.mm
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import "chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h"
-
-#include "chrome/browser/bookmarks/bookmark_model.h"
-
-@implementation BookmarkTreeBrowserCell
-
-@synthesize matrix = matrix_;
-@synthesize target = target_;
-@synthesize action = action_;
-
-- (const BookmarkNode*)bookmarkNode {
- return bookmarkNode_;
-}
-
-- (void)setBookmarkNode:(const BookmarkNode*)bookmarkNode {
- bookmarkNode_ = bookmarkNode;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm
deleted file mode 100644
index a8418e2..0000000
--- a/chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell_unittest.mm
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2010 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.
-
-#import <Cocoa/Cocoa.h>
-
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/bookmarks/bookmark_tree_browser_cell.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/platform_test.h"
-
-class BookmarkTreeBrowserCellTest : public PlatformTest {
- public:
- BookmarkTreeBrowserCellTest() {
- // Set up our mocks.
- GURL gurl;
- bookmarkNodeMock_.reset(new BookmarkNode(gurl));
- matrixMock_.reset([[NSMatrix alloc] init]);
- targetMock_.reset([[NSObject alloc] init]);
- }
-
- scoped_ptr<BookmarkNode> bookmarkNodeMock_;
- scoped_nsobject<NSMatrix> matrixMock_;
- scoped_nsobject<NSObject> targetMock_;
-};
-
-TEST_F(BookmarkTreeBrowserCellTest, BasicAllocDealloc) {
- BookmarkTreeBrowserCell* cell = [[[BookmarkTreeBrowserCell alloc]
- initTextCell:@"TEST STRING"] autorelease];
- [cell setMatrix:matrixMock_.get()];
- [cell setTarget:targetMock_.get()];
- [cell setAction:@selector(mockAction:)];
- [cell setBookmarkNode:bookmarkNodeMock_.get()];
-
- NSMatrix* testMatrix = [cell matrix];
- EXPECT_EQ(testMatrix, matrixMock_.get());
- id testTarget = [cell target];
- EXPECT_EQ(testTarget, targetMock_.get());
- SEL testAction = [cell action];
- EXPECT_EQ(testAction, @selector(mockAction:));
- const BookmarkNode* testBookmarkNode = [cell bookmarkNode];
- EXPECT_EQ(testBookmarkNode, bookmarkNodeMock_.get());
-}