diff --git a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/classes.nib b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/classes.nib index 24fa1f857d8..5c82bc0a320 100644 --- a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/classes.nib +++ b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/classes.nib @@ -1,6 +1,5 @@ { IBClasses = ( - {CLASS = ExtendedTableView; LANGUAGE = ObjC; SUPERCLASS = NSTableView; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, { CLASS = NSPreferencePane; @@ -15,26 +14,31 @@ }, { ACTIONS = { - clearCookies = id; clickAskAboutCookies = id; clickAutoFillPasswords = id; - clickEnableCookies = id; + clickCookieBehavior = id; clickStorePasswords = id; - editCookieSites = id; - editCookieSitesDone = id; + editCookies = id; + editCookiesDone = id; + editPermissions = id; + editPermissionsDone = id; launchKeychainAccess = id; - removeCookieSite = id; + removeAllCookiePermissions = id; + removeAllCookies = id; + removeCookiePermissions = id; + removeCookies = id; }; CLASS = OrgMozillaChimeraPreferencePrivacy; LANGUAGE = ObjC; OUTLETS = { mAskAboutCookies = NSButton; mAutoFillPasswords = NSButton; - mCookieSitePanel = id; - mCookiesEnabled = NSButton; - mEditSitesButton = NSButton; - mEditSitesText = NSTextField; - mSiteTable = ExtendedTableView; + mCookieBehavior = NSMatrix; + mCookiesPanel = id; + mCookiesTable = NSTableView; + mPermissionColumn = NSTableColumn; + mPermissionsPanel = id; + mPermissionsTable = NSTableView; mStorePasswords = NSButton; }; SUPERCLASS = PreferencePaneBase; diff --git a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/info.nib b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/info.nib index 3a89b4cd498..dc78b219f58 100644 --- a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/info.nib +++ b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/info.nib @@ -3,12 +3,12 @@ IBDocumentLocation - 133 69 356 240 0 0 1280 832 + 220 75 356 240 0 0 1280 832 IBFramework Version 362.0 IBOpenObjects - 287 + 5 IBSystem Version 7D24 diff --git a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/objects.nib b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/objects.nib index ea54c9fbbe1..a61ecd48b8a 100644 Binary files a/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/objects.nib and b/mozilla/camino/PreferencePanes/Privacy/English.lproj/Privacy.nib/objects.nib differ diff --git a/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.h b/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.h index 8b478d6478c..79c6de3a281 100644 --- a/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.h +++ b/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.h @@ -6,47 +6,66 @@ class nsIPref; class nsIPermissionManager; -class nsISimpleEnumerator; class nsIPermission; +class nsICookieManager; +class nsICookie; @interface OrgMozillaChimeraPreferencePrivacy : PreferencePaneBase { - IBOutlet NSButton* mCookiesEnabled; + // pane + IBOutlet NSMatrix* mCookieBehavior; IBOutlet NSButton* mAskAboutCookies; - IBOutlet id mCookieSitePanel; - IBOutlet NSButton* mEditSitesButton; - IBOutlet NSTextField* mEditSitesText; IBOutlet NSButton* mStorePasswords; IBOutlet NSButton* mAutoFillPasswords; - IBOutlet ExtendedTableView* mSiteTable; - nsIPermissionManager* mManager; // STRONG (should be nsCOMPtr) - nsCOMArray* mCachedPermissions; // parallel list of permissions for speed + // permission sheet + IBOutlet id mPermissionsPanel; + IBOutlet NSTableView* mPermissionsTable; + IBOutlet NSTableColumn* mPermissionColumn; + nsIPermissionManager* mPermissionManager; // STRONG (should be nsCOMPtr) + nsCOMArray* mCachedPermissions; // parallel list for speed, STRONG + + // cookie sheet + IBOutlet id mCookiesPanel; + IBOutlet NSTableView* mCookiesTable; + nsICookieManager* mCookieManager; + nsCOMArray* mCachedCookies; } --(IBAction) clearCookies:(id)aSender; --(IBAction) editCookieSites:(id)aSender; --(IBAction) editCookieSitesDone:(id)aSender; --(IBAction) removeCookieSite:(id)aSender; -- (void) editCookieSitesSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; - -// data source informal protocol (NSTableDataSource) -- (int)numberOfRowsInTableView:(NSTableView *)aTableView; -- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; - -// NSTableView delegate methods -- (void)tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)aTableColumn; - --(IBAction) clickEnableCookies:(id)sender; +// main panel button actions +-(IBAction) clickCookieBehavior:(id)aSender; -(IBAction) clickAskAboutCookies:(id)sender; - -(IBAction) clickStorePasswords:(id)sender; -(IBAction) clickAutoFillPasswords:(id)sender; -(IBAction) launchKeychainAccess:(id)sender; -// helpers going between the enable cookie checkbox and the mozilla pref --(BOOL)mapCookiePrefToCheckbox:(int)inCookiePref; --(int)mapCookieCheckboxToPref:(BOOL)inCheckboxValue; +// cookie editing functions +-(void) populateCookieCache; +-(IBAction) editCookies:(id)aSender; +-(IBAction) editCookiesDone:(id)aSender; +-(IBAction) removeCookies:(id)aSender; +-(IBAction) removeAllCookies:(id)aSender; + +// permission editing functions +-(void) populatePermissionCache; +-(IBAction) editPermissions:(id)aSender; +-(IBAction) editPermissionsDone:(id)aSender; +-(IBAction) removeCookiePermissions:(id)aSender; +-(IBAction) removeAllCookiePermissions:(id)aSender; + +-(void) mapCookiePrefToGUI:(int)pref; + +// data source informal protocol (NSTableDataSource) +- (int)numberOfRowsInTableView:(NSTableView *)aTableView; +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; +- (void)tableView:(NSTableView *)aTableView setObjectValue:anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex; + +// NSTableView delegate methods +- (void) tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)aTableColumn; + +// sorting support methods +-(void) sortCookiesByColumn:(NSTableColumn *)aTableColumn; +-(void) sortPermissionsByColumn:(NSTableColumn *)aTableColumn; @end diff --git a/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.mm b/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.mm index 3b6d322c247..2ca77a08a6b 100644 --- a/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.mm +++ b/mozilla/camino/PreferencePanes/Privacy/PrivacyPane.mm @@ -1,13 +1,17 @@ #import "PrivacyPane.h" +#import "NSString+Utils.h" #include "nsCOMPtr.h" #include "nsIServiceManagerUtils.h" #include "nsIPref.h" #include "nsNetCID.h" +#include "nsICookie.h" #include "nsICookieManager.h" #include "nsIPermissionManager.h" #include "nsISimpleEnumerator.h" #include "nsIPermission.h" +#include "nsIURI.h" +#include "nsNetUtil.h" #include "nsString.h" @@ -16,20 +20,26 @@ static const char* const gUseKeychainPref = "chimera.store_passwords_with_keycha static const char* const gAutoFillEnabledPref = "chimera.keychain_passwords_autofill"; // network.cookie.cookieBehavior settings -const int kEnableAllCookies = 0; -const int kDisableAllCookies = 2; +// these are the defaults, overriden by whitelist/blacklist +const int kAcceptAllCookies = 0; +const int kAcceptCookiesFromOriginatingServer = 1; +const int kDenyAllCookies = 2; // network.cookie.lifetimePolicy settings const int kAcceptCookiesNormally = 0; const int kWarnAboutCookies = 1; +// popup indices +const int kAllowIndex = 0; +const int kDenyIndex = 1; + // callbacks for sorting the permission list -PR_STATIC_CALLBACK(int) compareHosts(nsIPermission* aPerm1, nsIPermission* aPerm2, void* aData) +PR_STATIC_CALLBACK(int) comparePermHosts(nsIPermission* aPerm1, nsIPermission* aPerm2, void* aData) { nsCAutoString host1; - NS_CONST_CAST(nsIPermission*, aPerm1)->GetHost(host1); + aPerm1->GetHost(host1); nsCAutoString host2; - NS_CONST_CAST(nsIPermission*, aPerm2)->GetHost(host2); + aPerm2->GetHost(host2); return Compare(host1, host2); } @@ -37,68 +47,93 @@ PR_STATIC_CALLBACK(int) compareHosts(nsIPermission* aPerm1, nsIPermission* aPerm PR_STATIC_CALLBACK(int) compareCapabilities(nsIPermission* aPerm1, nsIPermission* aPerm2, void* aData) { PRUint32 cap1 = 0; - NS_CONST_CAST(nsIPermission*, aPerm1)->GetCapability(&cap1); + aPerm1->GetCapability(&cap1); PRUint32 cap2 = 0; - NS_CONST_CAST(nsIPermission*, aPerm2)->GetCapability(&cap2); + aPerm2->GetCapability(&cap2); if(cap1 == cap2) - return compareHosts(aPerm1, aPerm2, aData); + return comparePermHosts(aPerm1, aPerm2, aData); return (cap1 < cap2) ? -1 : 1; } +PR_STATIC_CALLBACK(int) compareCookieHosts(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + nsCAutoString host1; + aCookie1->GetHost(host1); + nsCAutoString host2; + aCookie2->GetHost(host2); + return Compare(host1, host2); +} + +PR_STATIC_CALLBACK(int) compareNames(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + nsCAutoString name1; + aCookie1->GetName(name1); + nsCAutoString name2; + aCookie2->GetName(name2); + return Compare(name1, name2); +} + +PR_STATIC_CALLBACK(int) comparePaths(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + nsCAutoString path1; + aCookie1->GetPath(path1); + nsCAutoString path2; + aCookie2->GetPath(path2); + return Compare(path1, path2); +} + +PR_STATIC_CALLBACK(int) compareSecures(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + PRBool secure1; + aCookie1->GetIsSecure(&secure1); + PRBool secure2; + aCookie2->GetIsSecure(&secure2); + if (secure1 == secure2) + return -1; + return (secure1) ? -1 : 1; +} + +PR_STATIC_CALLBACK(int) compareExpires(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + PRUint64 expires1; + aCookie1->GetExpires(&expires1); + PRUint64 expires2; + aCookie2->GetExpires(&expires2); + return (expires1 < expires2) ? -1 : 1; +} + +PR_STATIC_CALLBACK(int) compareValues(nsICookie* aCookie1, nsICookie* aCookie2, void* aData) +{ + nsCAutoString value1; + aCookie1->GetValue(value1); + nsCAutoString value2; + aCookie2->GetValue(value2); + return Compare(value1, value2); +} @implementation OrgMozillaChimeraPreferencePrivacy -- (void) dealloc +-(void) dealloc { - NS_IF_RELEASE(mManager); + // NOTE: no need to worry about mCachedPermissions or mCachedCookies because if we're going away + // the respective sheets have closed and cleaned up. + + NS_IF_RELEASE(mPermissionManager); + NS_IF_RELEASE(mCookieManager); [super dealloc]; } -// -// mapCookiePrefToCheckbox: -// -// Takes an int from the mozilla cookie pref and turns it into a BOOL -// that can be used by our "enable cookies" checkbox. -// --(BOOL)mapCookiePrefToCheckbox:(int)inCookiePref -{ - BOOL retval = YES; - if ( inCookiePref == kDisableAllCookies ) - retval = NO; - return retval; -} - -// -// mapCookieCheckboxToPref: -// -// Takes a BOOL from a checkbox and maps it to the mozilla pref values -// --(int)mapCookieCheckboxToPref:(BOOL)inCheckboxValue -{ - PRInt32 retval = kDisableAllCookies; - if ( inCheckboxValue ) - retval = kEnableAllCookies; - return retval; -} - -- (void)mainViewDidLoad +-(void) mainViewDidLoad { if ( !mPrefService ) return; - // Hookup cookie prefs. The "ask about" and "cookie sites" buttons need to - // be disabled when cookies aren't enabled because they aren't applicable. - PRInt32 acceptCookies = kEnableAllCookies; + // Hookup cookie prefs. + PRInt32 acceptCookies = kAcceptAllCookies; mPrefService->GetIntPref("network.cookie.cookieBehavior", &acceptCookies); - BOOL cookiesEnabled = [self mapCookiePrefToCheckbox:acceptCookies]; - [mCookiesEnabled setState:cookiesEnabled]; - if ( !cookiesEnabled ) { - [mAskAboutCookies setEnabled:NO]; - [mEditSitesButton setEnabled:NO]; - [mEditSitesText setTextColor:[NSColor lightGrayColor]]; - } + [self mapCookiePrefToGUI: acceptCookies]; // lifetimePolicy now controls asking about cookies, despite being totally unintuitive PRInt32 lifetimePolicy = kAcceptCookiesNormally; mPrefService->GetIntPref("network.cookie.lifetimePolicy", &lifetimePolicy); @@ -107,71 +142,140 @@ PR_STATIC_CALLBACK(int) compareCapabilities(nsIPermission* aPerm1, nsIPermission // store permission manager service and cache the enumerator. nsCOMPtr pm ( do_GetService(NS_PERMISSIONMANAGER_CONTRACTID) ); - mManager = pm.get(); - NS_IF_ADDREF(mManager); - - // Keychain checkboxes + mPermissionManager = pm.get(); + NS_IF_ADDREF(mPermissionManager); + // store cookie manager service + nsCOMPtr cm ( do_GetService(NS_COOKIEMANAGER_CONTRACTID) ); + mCookieManager = cm.get(); + NS_IF_ADDREF(mCookieManager); + + // Keychain checkboxes PRBool storePasswords = PR_TRUE; mPrefService->GetBoolPref(gUseKeychainPref, &storePasswords); [mStorePasswords setState:(storePasswords ? NSOnState : NSOffState)]; - [mAutoFillPasswords setEnabled:storePasswords ? YES : NO]; - + PRBool autoFillPasswords = PR_TRUE; mPrefService->GetBoolPref(gAutoFillEnabledPref, &autoFillPasswords); [mAutoFillPasswords setState:(autoFillPasswords ? NSOnState : NSOffState)]; + + // setup allow/deny table popups + NSPopUpButtonCell *popupButtonCell = [mPermissionColumn dataCell]; + [popupButtonCell setEditable:YES]; + [popupButtonCell addItemsWithTitles:[NSArray arrayWithObjects:[self getLocalizedString:@"Allow"], [self getLocalizedString:@"Deny"], nil]]; } -// -// clearCookies: -// -// Clear all the user's cookies. -// --(IBAction) clearCookies:(id)aSender +-(void) mapCookiePrefToGUI: (int)pref { - nsCOMPtr cookieMonster ( do_GetService(NS_COOKIEMANAGER_CONTRACTID) ); - if ( cookieMonster ) - cookieMonster->RemoveAll(); + [mCookieBehavior selectCellWithTag:pref]; + [mAskAboutCookies setEnabled:(pref == kAcceptAllCookies || pref == kAcceptCookiesFromOriginatingServer)]; } +// +// Stored cookie editing methods +// -// -// clickEnableCookies: -// -// Set cookie prefs and updates the enabled/disabled states of the -// "ask" and "edit sites" buttons. -// --(IBAction) clickEnableCookies:(id)sender +-(void) populateCookieCache { - if ( !mPrefService ) - return; - - // set the pref - BOOL enabled = [mCookiesEnabled state]; - [self setPref:"network.cookie.cookieBehavior" toInt:[self mapCookieCheckboxToPref:enabled]]; - - // update the buttons - [mAskAboutCookies setEnabled:enabled]; - [mEditSitesButton setEnabled:enabled]; - [mEditSitesText setTextColor:(enabled ? [NSColor blackColor] : [NSColor lightGrayColor])]; + nsCOMPtr cookieEnum; + if ( mCookieManager ) + mCookieManager->GetEnumerator(getter_AddRefs(cookieEnum)); + + mCachedCookies = new nsCOMArray; + if ( mCachedCookies && cookieEnum ) { + mCachedCookies->Clear(); + PRBool hasMoreElements = PR_FALSE; + cookieEnum->HasMoreElements(&hasMoreElements); + while ( hasMoreElements ) { + nsCOMPtr cookie; + cookieEnum->GetNext(getter_AddRefs(cookie)); + mCachedCookies->AppendObject(cookie); + cookieEnum->HasMoreElements(&hasMoreElements); + } + } } - --(IBAction) clickAskAboutCookies:(id)sender +-(IBAction) editCookies:(id)aSender { - [self setPref:"network.cookie.lifetimePolicy" toInt:([sender state] == NSOnState) ? kWarnAboutCookies : kAcceptCookiesNormally]; + // build parallel cookie list + [self populateCookieCache]; + + mCachedCookies->Sort(compareCookieHosts, nsnull); + + // ensure a row is selected (cocoa doesn't do this for us, but will keep + // us from unselecting a row once one is set; go figure). + [mCookiesTable selectRow: 0 byExtendingSelection: NO]; + [mCookiesTable setHighlightedTableColumn:[mCookiesTable tableColumnWithIdentifier:@"Website"]]; + + // we shouldn't need to do this, but the scrollbar won't enable unless we + // force the table to reload its data. Oddly it gets the number of rows correct, + // it just forgets to tell the scrollbar. *shrug* + [mCookiesTable reloadData]; + + // bring up sheet + [NSApp beginSheet:mCookiesPanel + modalForWindow:[mAskAboutCookies window] // any old window accessor + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; } +-(IBAction) removeCookies:(id)aSender +{ + if (mCachedCookies && mCookieManager) { + NSArray *rows = [[mCookiesTable selectedRowEnumerator] allObjects]; + NSEnumerator *e = [rows reverseObjectEnumerator]; + NSNumber *index; + while (index = [e nextObject]) + { + int row = [index intValue]; + nsCAutoString host, name, path; + mCachedCookies->ObjectAt(row)->GetHost(host); + mCachedCookies->ObjectAt(row)->GetName(name); + mCachedCookies->ObjectAt(row)->GetPath(path); + mCookieManager->Remove(host, name, path, PR_FALSE); // don't block permanently + mCachedCookies->RemoveObjectAt(row); + } + } + [mCookiesTable deselectAll: self]; // don't want any traces of previous selection + [mCookiesTable reloadData]; +} --(IBAction) editCookieSites:(id)aSender +-(IBAction) removeAllCookies: (id)aSender +{ + if ( mCookieManager ) { + // remove all cookies from cookie manager + mCookieManager->RemoveAll(); + // create new cookie cache + delete mCachedCookies; + mCachedCookies = nsnull; + mCachedCookies = new nsCOMArray; + } + [mCookiesTable reloadData]; +} + +-(IBAction) editCookiesDone:(id)aSender +{ + // save stuff + [mCookiesPanel orderOut:self]; + [NSApp endSheet:mCookiesPanel]; + + delete mCachedCookies; + mCachedCookies = nsnull; +} + +// +// Site permission editing methods + +-(void) populatePermissionCache { nsCOMPtr permEnum; - if ( mManager ) - mManager->GetEnumerator(getter_AddRefs(permEnum)); - - // build parallel permission list for speed with a lot of blocked sites + if ( mPermissionManager ) + mPermissionManager->GetEnumerator(getter_AddRefs(permEnum)); + mCachedPermissions = new nsCOMArray; if ( mCachedPermissions && permEnum ) { + mCachedPermissions->Clear(); PRBool hasMoreElements = PR_FALSE; permEnum->HasMoreElements(&hasMoreElements); while ( hasMoreElements ) { @@ -187,121 +291,279 @@ PR_STATIC_CALLBACK(int) compareCapabilities(nsIPermission* aPerm1, nsIPermission permEnum->HasMoreElements(&hasMoreElements); } } +} - mCachedPermissions->Sort(compareHosts, nsnull); +-(IBAction) editPermissions:(id)aSender +{ + // build parallel permission list for speed with a lot of blocked sites + [self populatePermissionCache]; + + mCachedPermissions->Sort(comparePermHosts, nsnull); - [NSApp beginSheet:mCookieSitePanel - modalForWindow:[mCookiesEnabled window] // any old window accessor - modalDelegate:self - didEndSelector:@selector(editCookieSitesSheetDidEnd:returnCode:contextInfo:) - contextInfo:NULL]; - // ensure a row is selected (cocoa doesn't do this for us, but will keep // us from unselecting a row once one is set; go figure). - [mSiteTable selectRow:0 byExtendingSelection:NO]; - [[mSiteTable window] makeFirstResponder:mSiteTable]; - - [mSiteTable setHighlightedTableColumn:[mSiteTable tableColumnWithIdentifier:@"Website"]]; - [mSiteTable setDeleteAction:@selector(removeCookieSite:)]; - [mSiteTable setTarget:self]; + [mPermissionsTable selectRow:0 byExtendingSelection:NO]; + [mPermissionsTable setHighlightedTableColumn:[mPermissionsTable tableColumnWithIdentifier:@"Website"]]; // we shouldn't need to do this, but the scrollbar won't enable unless we // force the table to reload its data. Oddly it gets the number of rows correct, // it just forgets to tell the scrollbar. *shrug* - [mSiteTable reloadData]; + [mPermissionsTable reloadData]; + + // bring up sheet + [NSApp beginSheet:mPermissionsPanel + modalForWindow:[mAskAboutCookies window] // any old window accessor + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; } --(IBAction) editCookieSitesDone:(id)aSender +-(IBAction) removeCookiePermissions:(id)aSender +{ + if ( mCachedPermissions && mPermissionManager ) { + // remove from parallel array and cookie permissions list + NSArray *rows = [[mPermissionsTable selectedRowEnumerator] allObjects]; + NSEnumerator *e = [rows reverseObjectEnumerator]; + NSNumber *index; + while (index = [e nextObject]) { + int row = [index intValue]; + nsCAutoString host; + mCachedPermissions->ObjectAt(row)->GetHost(host); + mPermissionManager->Remove(host, "cookie"); + mCachedPermissions->RemoveObjectAt(row); + } + } + [mPermissionsTable deselectAll: self]; // don't want any traces of previous selection + [mPermissionsTable reloadData]; +} + +-(IBAction) removeAllCookiePermissions: (id)aSender +{ + if ( mPermissionManager ) { + // remove all permissions from permission manager + mPermissionManager->RemoveAll(); + delete mCachedPermissions; + mCachedPermissions = nsnull; + mCachedPermissions = new nsCOMArray; + } + [mPermissionsTable reloadData]; +} + +-(IBAction) editPermissionsDone:(id)aSender { // save stuff - - [mCookieSitePanel orderOut:self]; - [NSApp endSheet:mCookieSitePanel]; + [mPermissionsPanel orderOut:self]; + [NSApp endSheet:mPermissionsPanel]; delete mCachedPermissions; mCachedPermissions = nsnull; } -- (void)editCookieSitesSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo -{ -} - - --(IBAction) removeCookieSite:(id)aSender -{ - if ( mCachedPermissions && mManager ) { - // remove from parallel array and cookie permissions list - int row = [mSiteTable selectedRow]; - - // remove from permission manager (which is done by host, not by row), then - // remove it from our parallel array (which is done by row). Since we keep a - // parallel array, removing multiple items by row is very difficult since after - // deleting, the array is out of sync with the next cocoa row we're told to remove. Punt! - nsCAutoString host; - nsIPermission* perm = mCachedPermissions->ObjectAt(row); - if (perm) { - perm->GetHost(host); - mManager->Remove(host, "cookie"); // could this api _be_ any worse? Come on! - mCachedPermissions->RemoveObjectAt(row); - } - - [mSiteTable reloadData]; - } -} - - // // NSTableDataSource protocol methods // -- (int)numberOfRowsInTableView:(NSTableView *)aTableView +-(int) numberOfRowsInTableView:(NSTableView *)aTableView { PRUint32 numRows = 0; - if ( mCachedPermissions ) - numRows = mCachedPermissions->Count(); + if (aTableView == mPermissionsTable) { + if ( mCachedPermissions ) + numRows = mCachedPermissions->Count(); + } else if (aTableView == mCookiesTable) { + if ( mCachedCookies ) + numRows = mCachedCookies->Count(); + } return (int) numRows; } -- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex +-(id) tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { NSString* retVal = nil; - if ( mCachedPermissions ) { - if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) { + if (aTableView == mPermissionsTable) { + if ( mCachedPermissions ) { + if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) { // website url column nsCAutoString host; mCachedPermissions->ObjectAt(rowIndex)->GetHost(host); - retVal = [NSString stringWithCString:host.get()]; - } else { + retVal = [NSString stringWithUTF8String:host.get()]; + } else { // allow/deny column PRUint32 capability = PR_FALSE; mCachedPermissions->ObjectAt(rowIndex)->GetCapability(&capability); - if ( capability == nsIPermissionManager::ALLOW_ACTION) - retVal = [self getLocalizedString:@"Allow"]; + if ( capability == nsIPermissionManager::ALLOW_ACTION ) + return [NSNumber numberWithInt:kAllowIndex]; // special case return else - retVal = [self getLocalizedString:@"Deny"]; + return [NSNumber numberWithInt:kDenyIndex]; // special case return + } } } - + else if (aTableView == mCookiesTable) { + if ( mCachedCookies ) { + nsCAutoString cookieVal; + if ( [[aTableColumn identifier] isEqualToString: @"Website"] ) { + mCachedCookies->ObjectAt(rowIndex)->GetHost(cookieVal); + } else if ( [[aTableColumn identifier] isEqualToString: @"Name"] ) { + mCachedCookies->ObjectAt(rowIndex)->GetName(cookieVal); + } else if ( [[aTableColumn identifier] isEqualToString: @"Path"] ) { + mCachedCookies->ObjectAt(rowIndex)->GetPath(cookieVal); + } else if ( [[aTableColumn identifier] isEqualToString: @"Secure"] ) { + PRBool secure = PR_FALSE; + mCachedCookies->ObjectAt(rowIndex)->GetIsSecure(&secure); + if (secure) + cookieVal = "yes"; + else + cookieVal = "no"; + } else if ( [[aTableColumn identifier] isEqualToString: @"Expires"] ) { + PRUint64 expires = 0; + mCachedCookies->ObjectAt(rowIndex)->GetExpires(&expires); + if (expires == 0) { + // if expires is 0, it's a session cookie; display as expiring on the current date. + // It's not perfect, but it's better than showing the epoch. + NSDate *date = [NSDate date]; + return date; // special case return + } else { + NSDate *date = [NSDate dateWithTimeIntervalSince1970: (NSTimeInterval)expires]; + return date; // special case return + } + } else if ( [[aTableColumn identifier] isEqualToString: @"Value"] ) { + mCachedCookies->ObjectAt(rowIndex)->GetValue(cookieVal); + } + retVal = [NSString stringWithCString: cookieVal.get()]; + } + } + return retVal; } +// currently, this only applies to the site allow/deny, since that's the only editable column +-(void) tableView:(NSTableView *)aTableView + setObjectValue:anObject + forTableColumn:(NSTableColumn *)aTableColumn + row:(int)rowIndex +{ + if ( aTableView == mPermissionsTable && aTableColumn == mPermissionColumn ) { + if ( mCachedPermissions && mPermissionManager ) { + // create a URI from the hostname of the changed site + nsCAutoString host; + mCachedPermissions->ObjectAt(rowIndex)->GetHost(host); + NSString* url = [NSString stringWithFormat:@"http://%s", host.get()]; + const char* siteURL = [url UTF8String]; + nsCOMPtr newURI; + NS_NewURI(getter_AddRefs(newURI), siteURL); + if ( newURI ) { + // nsIPermissions are immutable, and there's no API to change the action, + // so instead we have to delete the old pref and insert a new one. + // remove the old entry + mPermissionManager->Remove(host, "cookie"); + // add a new entry with the new permission + if ( [anObject intValue] == kAllowIndex ) + mPermissionManager->Add(newURI, "cookie", nsIPermissionManager::ALLOW_ACTION); + else if ( [anObject intValue] == kDenyIndex ) + mPermissionManager->Add(newURI, "cookie", nsIPermissionManager::DENY_ACTION); + + // there really should be a better way to keep the cache up-to-date than rebuilding + // it, but the nsIPermissionManager interface doesn't have a way to get a pointer + // to a site's nsIPermission. It's this, use a custom class that duplicates the + // information (wasting a lot of memory), or find a way to tie in to + // PERM_CHANGE_NOTIFICATION to get the new nsIPermission that way. + [self populatePermissionCache]; + //re-sort + [self sortPermissionsByColumn:[mPermissionsTable highlightedTableColumn]]; + } + } + } +} + +-(void) sortPermissionsByColumn:(NSTableColumn *)aTableColumn +{ + if( mCachedPermissions ) { + if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) + mCachedPermissions->Sort(comparePermHosts, nsnull); + else + mCachedPermissions->Sort(compareCapabilities, nsnull); + [mPermissionsTable setHighlightedTableColumn:aTableColumn]; + [mPermissionsTable reloadData]; + } +} + +-(void) sortCookiesByColumn:(NSTableColumn *)aTableColumn +{ + if( mCachedCookies ) { + if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) + mCachedCookies->Sort(compareCookieHosts, nsnull); + else if ( [[aTableColumn identifier] isEqualToString:@"Name"] ) + mCachedCookies->Sort(compareNames, nsnull); + else if ( [[aTableColumn identifier] isEqualToString:@"Path"] ) + mCachedCookies->Sort(comparePaths, nsnull); + else if ( [[aTableColumn identifier] isEqualToString:@"Secure"] ) + mCachedCookies->Sort(compareSecures, nsnull); + else if ( [[aTableColumn identifier] isEqualToString:@"Expires"] ) + mCachedCookies->Sort(compareExpires, nsnull); + else if ( [[aTableColumn identifier] isEqualToString:@"Value"] ) + mCachedCookies->Sort(compareValues, nsnull); + [mCookiesTable setHighlightedTableColumn:aTableColumn]; + [mCookiesTable reloadData]; + } +} // NSTableView delegate methods -- (void)tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)aTableColumn +- (void) tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)aTableColumn { - if( mCachedPermissions && aTableColumn != [aTableView highlightedTableColumn] ) { - if ( [[aTableColumn identifier] isEqualToString:@"Website"] ) - mCachedPermissions->Sort(compareHosts, nsnull); - else - mCachedPermissions->Sort(compareCapabilities, nsnull); - - [aTableView setHighlightedTableColumn:aTableColumn]; - [aTableView reloadData]; + if (aTableView == mPermissionsTable) { + if ( mCachedPermissions && aTableColumn != [aTableView highlightedTableColumn] ) { + // save the currently selected row, if any. + int selectedRowIndex = [aTableView selectedRow]; + nsCOMPtr selectedItem = (selectedRowIndex != -1) ? + mCachedPermissions->ObjectAt(selectedRowIndex) : nsnull; + // sort the table data + [self sortPermissionsByColumn:aTableColumn]; + // if a row was selected before, find it again + if ( selectedItem ) { + int newRowIndex = mCachedPermissions->IndexOf(selectedItem); + if ( newRowIndex >= 0 ) { + [aTableView selectRow:newRowIndex byExtendingSelection:NO]; + [aTableView scrollRowToVisible:newRowIndex]; + } + } + } + } else if (aTableView == mCookiesTable) { + if ( mCachedCookies && aTableColumn != [aTableView highlightedTableColumn] ) { + // save the currently selected row, if any + int selectedRowIndex = [aTableView selectedRow]; + nsCOMPtr selectedItem = (selectedRowIndex != -1) ? + mCachedCookies->ObjectAt(selectedRowIndex) : nsnull; + // sort the table data + [self sortCookiesByColumn:aTableColumn]; + // if a row was selected before, find it again + if ( selectedItem ) { + int newRowIndex = mCachedCookies->IndexOf(selectedItem); + if ( newRowIndex >= 0 ) { + [aTableView selectRow:newRowIndex byExtendingSelection:NO]; + [aTableView scrollRowToVisible:newRowIndex]; + } + } + } } } +// +// Buttons +// + +-(IBAction) clickCookieBehavior:(id)sender +{ + int row = [mCookieBehavior selectedRow]; + [self setPref:"network.cookie.cookieBehavior" toInt:row]; + [self mapCookiePrefToGUI:row]; +} + +-(IBAction) clickAskAboutCookies:(id)sender +{ + [self setPref:"network.cookie.lifetimePolicy" toInt:([sender state] == NSOnState) ? kWarnAboutCookies : kAcceptCookiesNormally]; +} + // // clickStorePasswords @@ -310,16 +572,9 @@ PR_STATIC_CALLBACK(int) compareCapabilities(nsIPermission* aPerm1, nsIPermission { if ( !mPrefService ) return; - if([mStorePasswords state] == NSOnState) - { - mPrefService->SetBoolPref("chimera.store_passwords_with_keychain", PR_TRUE); - [mAutoFillPasswords setEnabled:YES]; - } - else - { - mPrefService->SetBoolPref("chimera.store_passwords_with_keychain", PR_FALSE); - [mAutoFillPasswords setEnabled:NO]; - } + mPrefService->SetBoolPref("chimera.store_passwords_with_keychain", + ([mStorePasswords state] == NSOnState) ? PR_TRUE : PR_FALSE); + [mAutoFillPasswords setEnabled:([mStorePasswords state] == NSOnState)]; } // @@ -332,7 +587,7 @@ PR_STATIC_CALLBACK(int) compareCapabilities(nsIPermission* aPerm1, nsIPermission if ( !mPrefService ) return; mPrefService->SetBoolPref("chimera.keychain_passwords_autofill", - [mAutoFillPasswords state] == NSOnState ? PR_TRUE : PR_FALSE); + ([mAutoFillPasswords state] == NSOnState) ? PR_TRUE : PR_FALSE); } -(IBAction) launchKeychainAccess:(id)sender diff --git a/mozilla/camino/src/preferences/PreferenceManager.mm b/mozilla/camino/src/preferences/PreferenceManager.mm index c2f212bcda1..5c488fb5c7f 100644 --- a/mozilla/camino/src/preferences/PreferenceManager.mm +++ b/mozilla/camino/src/preferences/PreferenceManager.mm @@ -309,11 +309,7 @@ static BOOL gMadePrefManager; PRInt32 acceptCookies = 0; static const char* kCookieBehaviorPref = "network.cookie.cookieBehavior"; mPrefs->GetIntPref(kCookieBehaviorPref, &acceptCookies); - if ( acceptCookies == 1 ) { // accept foreign cookies, assume off - acceptCookies = 2; - mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies); - } - else if ( acceptCookies == 3 ) { // p3p, assume all cookies on + if ( acceptCookies == 3 ) { // p3p, assume all cookies on acceptCookies = 0; mPrefs->SetIntPref(kCookieBehaviorPref, acceptCookies); }