Commit 9e4683cd authored by rsesek@chromium.org's avatar rsesek@chromium.org

[Mac] Add local storage nodes to the cookie manager

* Add local storage getters to CookieTreeNode
* XIB: Embed cookie info labels into an NSView (inside the NSBox) and add
  another for info NSView for local storage.
* Roll GTM r280:293

BUG=33068
TEST=Chromium-->Preferences-->Under the Hood-->Show cookies... Find and click on a local storage node. Info should be displayed.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38504 0039d316-1c4b-4281-b951-d872f2087c98
parent 2559e45a
...@@ -150,7 +150,7 @@ deps_os = { ...@@ -150,7 +150,7 @@ deps_os = {
"/trunk/deps/reference_builds/chrome_mac@35421", "/trunk/deps/reference_builds/chrome_mac@35421",
"src/third_party/GTM": "src/third_party/GTM":
"http://google-toolbox-for-mac.googlecode.com/svn/trunk@280", "http://google-toolbox-for-mac.googlecode.com/svn/trunk@293",
"src/third_party/pdfsqueeze": "src/third_party/pdfsqueeze":
"http://pdfsqueeze.googlecode.com/svn/trunk@2", "http://pdfsqueeze.googlecode.com/svn/trunk@2",
"src/third_party/lighttpd": "src/third_party/lighttpd":
......
This diff is collapsed.
// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -7,27 +7,46 @@ ...@@ -7,27 +7,46 @@
#include "base/scoped_nsobject.h" #include "base/scoped_nsobject.h"
#include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/cookies_tree_model.h"
// This enum specifies the type of display node a CocoaCookieTreeNode is. If
// this system is rewritten to not use bindings, this class should be
// subclassed and specialized, rather than using an enum to determine type.
enum CocoaCookieTreeNodeType {
// Represents grouping data for the actual data.
kCocoaCookieTreeNodeTypeFolder = 0,
// A cookie node.
kCocoaCookieTreeNodeTypeCookie = 1,
// A local storage node.
kCocoaCookieTreeNodeTypeLocalStorage = 2
};
// This class is used by CookiesWindowController and represents a node in the // This class is used by CookiesWindowController and represents a node in the
// cookie tree view. // cookie tree view.
@interface CocoaCookieTreeNode : NSObject { @interface CocoaCookieTreeNode : NSObject {
scoped_nsobject<NSString> title_; scoped_nsobject<NSString> title_;
scoped_nsobject<NSMutableArray> children_; scoped_nsobject<NSMutableArray> children_;
// We lazily create children, so we need to know if we are a leaf.
BOOL isLeaf_; CocoaCookieTreeNodeType nodeType_;
// The platform-independent model node. // The platform-independent model node.
CookieTreeNode* treeNode_; // weak CookieTreeNode* treeNode_; // weak
// These members are only set for true cookie nodes. // These members are only set for kCocoaCookieTreeNodeTypeCookie nodes.
BOOL isCookie_;
scoped_nsobject<NSString> name_; scoped_nsobject<NSString> name_;
scoped_nsobject<NSString> content_; scoped_nsobject<NSString> content_;
scoped_nsobject<NSString> domain_;
scoped_nsobject<NSString> path_; scoped_nsobject<NSString> path_;
scoped_nsobject<NSString> sendFor_; scoped_nsobject<NSString> sendFor_;
// Stringifed dates. // Stringifed dates.
scoped_nsobject<NSString> created_; scoped_nsobject<NSString> created_;
scoped_nsobject<NSString> expires_; scoped_nsobject<NSString> expires_;
// These members are only set for kCocoaCookieTreeNodeTypeLocalStorage nodes.
scoped_nsobject<NSString> fileSize_;
scoped_nsobject<NSString> lastModified_;
// These members are set for both of the two specialized node types.
scoped_nsobject<NSString> domain_;
} }
// Designated initializer. // Designated initializer.
...@@ -36,20 +55,18 @@ ...@@ -36,20 +55,18 @@
// Re-sets all the members of the node based on |treeNode_|. // Re-sets all the members of the node based on |treeNode_|.
- (void)rebuild; - (void)rebuild;
- (BOOL)isLeaf; // Common getters..
// Getters.
- (NSString*)title; - (NSString*)title;
- (CocoaCookieTreeNodeType)nodeType;
- (TreeModelNode*)treeNode;
// |-mutableChildren| exists so that the CookiesTreeModelObserverBridge can // |-mutableChildren| exists so that the CookiesTreeModelObserverBridge can
// operate on the children. Note that this lazily creates children. // operate on the children. Note that this lazily creates children.
- (NSMutableArray*)mutableChildren; - (NSMutableArray*)mutableChildren;
- (NSArray*)children; - (NSArray*)children;
- (BOOL)isLeaf;
- (TreeModelNode*)treeNode; // Used only by kCocoaCookieTreeNodeTypeCookie. Nil for other types.
// Used only by cookies. Nil for non-cookie nodes.
- (BOOL)isCookie;
- (NSString*)name; - (NSString*)name;
- (NSString*)content; - (NSString*)content;
- (NSString*)domain; - (NSString*)domain;
...@@ -58,4 +75,8 @@ ...@@ -58,4 +75,8 @@
- (NSString*)created; - (NSString*)created;
- (NSString*)expires; - (NSString*)expires;
// Used by kCocoaCookieTreeNodeTypeLocalStorage nodes. Nil for other types.
- (NSString*)fileSize;
- (NSString*)lastModified;
@end @end
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "app/l10n_util_mac.h" #include "app/l10n_util_mac.h"
#import "base/i18n/time_formatting.h" #import "base/i18n/time_formatting.h"
#include "base/sys_string_conversions.h" #include "base/sys_string_conversions.h"
#include "chrome/browser/browsing_data_local_storage_helper.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
@implementation CocoaCookieTreeNode @implementation CocoaCookieTreeNode
...@@ -15,8 +16,6 @@ ...@@ -15,8 +16,6 @@
if ((self = [super init])) { if ((self = [super init])) {
DCHECK(node); DCHECK(node);
treeNode_ = node; treeNode_ = node;
isLeaf_ = (node->GetChildCount() == 0);
[self rebuild]; [self rebuild];
} }
return self; return self;
...@@ -24,11 +23,13 @@ ...@@ -24,11 +23,13 @@
- (void)rebuild { - (void)rebuild {
title_.reset([base::SysWideToNSString(treeNode_->GetTitle()) retain]); title_.reset([base::SysWideToNSString(treeNode_->GetTitle()) retain]);
isCookie_ = NO; children_.reset();
nodeType_ = kCocoaCookieTreeNodeTypeFolder;
CookieTreeNode::DetailedInfo info = treeNode_->GetDetailedInfo(); CookieTreeNode::DetailedInfo info = treeNode_->GetDetailedInfo();
if (info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) { CookieTreeNode::DetailedInfo::NodeType nodeType = info.node_type;
isCookie_ = YES; if (nodeType == CookieTreeNode::DetailedInfo::TYPE_COOKIE) {
nodeType_ = kCocoaCookieTreeNodeTypeCookie;
net::CookieMonster::CanonicalCookie cookie = info.cookie->second; net::CookieMonster::CanonicalCookie cookie = info.cookie->second;
name_.reset([base::SysUTF8ToNSString(cookie.Name()) retain]); name_.reset([base::SysUTF8ToNSString(cookie.Name()) retain]);
...@@ -55,17 +56,31 @@ ...@@ -55,17 +56,31 @@
sendFor_.reset([l10n_util::GetNSStringWithFixup( sendFor_.reset([l10n_util::GetNSStringWithFixup(
IDS_COOKIES_COOKIE_SENDFOR_ANY) retain]); IDS_COOKIES_COOKIE_SENDFOR_ANY) retain]);
} }
} else if (nodeType == CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) {
const BrowsingDataLocalStorageHelper::LocalStorageInfo* storageInfo =
info.local_storage_info;
nodeType_ = kCocoaCookieTreeNodeTypeLocalStorage;
domain_.reset([base::SysUTF8ToNSString(storageInfo->origin) retain]);
fileSize_.reset([base::SysWideToNSString(FormatBytes(storageInfo->size,
GetByteDisplayUnits(storageInfo->size), true)) retain]);
lastModified_.reset([base::SysWideToNSString(
base::TimeFormatFriendlyDateAndTime(
storageInfo->last_modified)) retain]);
} }
} }
- (BOOL)isLeaf {
return isLeaf_;
}
- (NSString*)title { - (NSString*)title {
return title_.get(); return title_.get();
} }
- (CocoaCookieTreeNodeType)nodeType {
return nodeType_;
}
- (TreeModelNode*)treeNode {
return treeNode_;
}
- (NSMutableArray*)mutableChildren { - (NSMutableArray*)mutableChildren {
if (!children_.get()) { if (!children_.get()) {
const int childCount = treeNode_->GetChildCount(); const int childCount = treeNode_->GetChildCount();
...@@ -84,16 +99,19 @@ ...@@ -84,16 +99,19 @@
return [self mutableChildren]; return [self mutableChildren];
} }
- (TreeModelNode*)treeNode { - (BOOL)isLeaf {
return treeNode_; return nodeType_ != kCocoaCookieTreeNodeTypeFolder;
} }
#pragma mark Cookie Accessors - (NSString*)description {
NSString* format =
- (BOOL)isCookie { @"<CocoaCookieTreeNode @ %p (title=%@, nodeType=%d, childCount=%u)";
return isCookie_; return [NSString stringWithFormat:format, self, [self title],
[self nodeType], [[self children] count]];
} }
#pragma mark Cookie Accessors
- (NSString*)name { - (NSString*)name {
return name_.get(); return name_.get();
} }
...@@ -122,4 +140,14 @@ ...@@ -122,4 +140,14 @@
return expires_.get(); return expires_.get();
} }
#pragma mark Local Storage Accessors
- (NSString*)fileSize {
return fileSize_.get();
}
- (NSString*)lastModified {
return lastModified_.get();
}
@end @end
...@@ -94,6 +94,11 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver { ...@@ -94,6 +94,11 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver {
IBOutlet NSOutlineView* outlineView_; IBOutlet NSOutlineView* outlineView_;
IBOutlet NSSearchField* searchField_; IBOutlet NSSearchField* searchField_;
// These views are laid out inside a NSBox and are shown/hidden to detail
// information about the selected node.
IBOutlet NSView* cookieInfo_;
IBOutlet NSView* localStorageInfo_;
Profile* profile_; // weak Profile* profile_; // weak
BrowsingDataLocalStorageHelper* storageHelper_; // weak BrowsingDataLocalStorageHelper* storageHelper_; // weak
} }
...@@ -130,5 +135,7 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver { ...@@ -130,5 +135,7 @@ class CookiesTreeModelObserverBridge : public TreeModelObserver {
- (void)clearBrowsingDataNotification:(NSNotification*)notif; - (void)clearBrowsingDataNotification:(NSNotification*)notif;
- (CookiesTreeModelObserverBridge*)modelObserver; - (CookiesTreeModelObserverBridge*)modelObserver;
- (NSArray*)icons; - (NSArray*)icons;
- (NSView*)cookieInfoView;
- (NSView*)localStorageInfoView;
- (void)loadTreeModelFromProfile; - (void)loadTreeModelFromProfile;
@end @end
...@@ -320,7 +320,8 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { ...@@ -320,7 +320,8 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
- (void)outlineViewSelectionDidChange:(NSNotification*)notif { - (void)outlineViewSelectionDidChange:(NSNotification*)notif {
// Multi-selection should be disabled in the UI, but for sanity, double-check // Multi-selection should be disabled in the UI, but for sanity, double-check
// that they can't do it here. // that they can't do it here.
NSUInteger count = [[treeController_ selectedObjects] count]; NSArray* selectedObjects = [treeController_ selectedObjects];
NSUInteger count = [selectedObjects count];
if (count != 1U) { if (count != 1U) {
DCHECK_LT(count, 1U) << "User was able to select more than 1 cookie node!"; DCHECK_LT(count, 1U) << "User was able to select more than 1 cookie node!";
[self setRemoveButtonEnabled:NO]; [self setRemoveButtonEnabled:NO];
...@@ -342,6 +343,14 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { ...@@ -342,6 +343,14 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
} }
[self setRemoveButtonEnabled:YES]; [self setRemoveButtonEnabled:YES];
CocoaCookieTreeNodeType nodeType = [[selectedObjects lastObject] nodeType];
if (nodeType == kCocoaCookieTreeNodeTypeLocalStorage) {
[cookieInfo_ setHidden:YES];
[localStorageInfo_ setHidden:NO];
} else {
[cookieInfo_ setHidden:NO];
[localStorageInfo_ setHidden:YES];
}
} }
#pragma mark Unit Testing #pragma mark Unit Testing
...@@ -354,6 +363,14 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() { ...@@ -354,6 +363,14 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
return icons_.get(); return icons_.get();
} }
- (NSView*)cookieInfoView {
return cookieInfo_;
}
- (NSView*)localStorageInfoView {
return localStorageInfo_;
}
// Re-initializes the |treeModel_|, creates a new observer for it, and re- // Re-initializes the |treeModel_|, creates a new observer for it, and re-
// builds the |cocoaTreeModel_|. We use this to initialize the controller and // builds the |cocoaTreeModel_|. We use this to initialize the controller and
// to rebuild after the user clears browsing data. Because the models get // to rebuild after the user clears browsing data. Because the models get
......
// Copyright (c) 2009-2010 The Chromium Authors. All rights reserved. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -73,7 +73,7 @@ class CookiesWindowControllerTest : public CocoaTest { ...@@ -73,7 +73,7 @@ class CookiesWindowControllerTest : public CocoaTest {
protected: protected:
BrowserTestHelper browser_helper_; BrowserTestHelper browser_helper_;
scoped_nsobject<CookiesWindowController> controller_; scoped_nsobject<CookiesWindowController> controller_;
BrowsingDataLocalStorageHelper* local_storage_helper_; MockBrowsingDataLocalStorageHelper* local_storage_helper_;
}; };
TEST_F(CookiesWindowControllerTest, Construction) { TEST_F(CookiesWindowControllerTest, Construction) {
...@@ -437,9 +437,12 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) { ...@@ -437,9 +437,12 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) {
// This will clean itself up when we call |-closeSheet:|. If we reset the // This will clean itself up when we call |-closeSheet:|. If we reset the
// scoper, we'd get a double-free. // scoper, we'd get a double-free.
local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile);
local_storage_helper_->AddLocalStorageSamples();
CookiesWindowController* controller = CookiesWindowController* controller =
[[CookiesWindowController alloc] initWithProfile:profile [[CookiesWindowController alloc] initWithProfile:profile
storageHelper:local_storage_helper_]; storageHelper:local_storage_helper_];
local_storage_helper_->Notify();
[controller attachSheetTo:test_window()]; [controller attachSheetTo:test_window()];
// Nothing should be selected right now. // Nothing should be selected right now.
...@@ -452,6 +455,8 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) { ...@@ -452,6 +455,8 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) {
[[controller treeController] setSelectionIndexPath:indexPath]; [[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil]; [controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]); EXPECT_TRUE([controller removeButtonEnabled]);
EXPECT_FALSE([[controller cookieInfoView] isHidden]);
EXPECT_TRUE([[controller localStorageInfoView] isHidden]);
} }
{ {
...@@ -461,6 +466,19 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) { ...@@ -461,6 +466,19 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) {
[[controller treeController] setSelectionIndexPath:indexPath]; [[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil]; [controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]); EXPECT_TRUE([controller removeButtonEnabled]);
EXPECT_FALSE([[controller cookieInfoView] isHidden]);
EXPECT_TRUE([[controller localStorageInfoView] isHidden]);
}
{
// Select a local storage node.
NSUInteger path[3] = {2, 0, 0};
NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3];
[[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]);
EXPECT_TRUE([[controller cookieInfoView] isHidden]);
EXPECT_FALSE([[controller localStorageInfoView] isHidden]);
} }
{ {
...@@ -474,7 +492,7 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) { ...@@ -474,7 +492,7 @@ TEST_F(CookiesWindowControllerTest, RemoveButtonEnabled) {
{ {
// Try selecting something that doesn't exist again. // Try selecting something that doesn't exist again.
NSUInteger path[3] = {3, 1, 4}; NSUInteger path[3] = {7, 1, 4};
NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3]; NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:path length:3];
[[controller treeController] setSelectionIndexPath:indexPath]; [[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil]; [controller outlineViewSelectionDidChange:nil];
...@@ -536,4 +554,61 @@ TEST_F(CookiesWindowControllerTest, UpdateFilter) ...@@ -536,4 +554,61 @@ TEST_F(CookiesWindowControllerTest, UpdateFilter)
EXPECT_EQ(1U, [[[controller_ cocoaTreeModel] children] count]); EXPECT_EQ(1U, [[[controller_ cocoaTreeModel] children] count]);
} }
TEST_F(CookiesWindowControllerTest, CreateLocalStorageNodes) {
TestingProfile* profile = browser_helper_.profile();
net::CookieMonster* cm = profile->GetCookieMonster();
cm->SetCookie(GURL("http://google.com"), "A=B");
cm->SetCookie(GURL("http://dev.chromium.org"), "C=D");
local_storage_helper_ = new MockBrowsingDataLocalStorageHelper(profile);
local_storage_helper_->AddLocalStorageSamples();
controller_.reset(
[[CookiesWindowController alloc] initWithProfile:profile
storageHelper:local_storage_helper_]);
local_storage_helper_->Notify();
ASSERT_EQ(4U, [[[controller_ cocoaTreeModel] children] count]);
// Root --> host1.
CocoaCookieTreeNode* node =
[[[controller_ cocoaTreeModel] children] objectAtIndex:2];
EXPECT_TRUE([@"host1" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeFolder, [node nodeType]);
EXPECT_EQ(1U, [[node children] count]);
// host1 --> Local Storage.
node = [[node children] lastObject];
EXPECT_TRUE([@"Local Storage" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeFolder, [node nodeType]);
EXPECT_EQ(1U, [[node children] count]);
// Local Storage --> origin1.
node = [[node children] lastObject];
EXPECT_TRUE([@"origin1" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeLocalStorage, [node nodeType]);
EXPECT_TRUE([@"origin1" isEqualToString:[node domain]]);
EXPECT_TRUE([node lastModified]);
EXPECT_TRUE([node fileSize]);
// Root --> host2.
node =
[[[controller_ cocoaTreeModel] children] objectAtIndex:3];
EXPECT_TRUE([@"host2" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeFolder, [node nodeType]);
EXPECT_EQ(1U, [[node children] count]);
// host2 --> Local Storage.
node = [[node children] lastObject];
EXPECT_TRUE([@"Local Storage" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeFolder, [node nodeType]);
EXPECT_EQ(1U, [[node children] count]);
// Local Storage --> origin2.
node = [[node children] lastObject];
EXPECT_TRUE([@"origin2" isEqualToString:[node title]]);
EXPECT_EQ(kCocoaCookieTreeNodeTypeLocalStorage, [node nodeType]);
EXPECT_TRUE([@"origin2" isEqualToString:[node domain]]);
EXPECT_TRUE([node lastModified]);
EXPECT_TRUE([node fileSize]);
}
} // namespace } // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment