diff --git a/ClickToFlash.xcodeproj/project.pbxproj b/ClickToFlash.xcodeproj/project.pbxproj index 48533b10..dfcd8f30 100755 --- a/ClickToFlash.xcodeproj/project.pbxproj +++ b/ClickToFlash.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ 845704550F4792320017F3F4 /* CTFWhitelist.m in Sources */ = {isa = PBXBuildFile; fileRef = 845704540F4792320017F3F4 /* CTFWhitelist.m */; }; 8457045A0F47BC170017F3F4 /* CTFUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 845704590F47BC170017F3F4 /* CTFUtilities.m */; }; A494CC2C0F9F2446007D5EEB /* ctf.icns in Resources */ = {isa = PBXBuildFile; fileRef = A494CC2B0F9F2446007D5EEB /* ctf.icns */; }; + A4DEFC7A0FF33F7400CCB6A8 /* CTFPreferencesDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = A4DEFC770FF33F7400CCB6A8 /* CTFPreferencesDictionary.m */; }; + A4DEFC7B0FF33F7400CCB6A8 /* CTFUserDefaultsController.m in Sources */ = {isa = PBXBuildFile; fileRef = A4DEFC790FF33F7400CCB6A8 /* CTFUserDefaultsController.m */; }; D9566D8C0F380C9F00358646 /* sifr2-addons.js in Resources */ = {isa = PBXBuildFile; fileRef = D9566C2C0F37EA0800358646 /* sifr2-addons.js */; }; D9566D8D0F380C9F00358646 /* sifr3-addons.js in Resources */ = {isa = PBXBuildFile; fileRef = D9566C2D0F37EA0800358646 /* sifr3-addons.js */; }; /* End PBXBuildFile section */ @@ -151,6 +153,10 @@ 845704580F47BC170017F3F4 /* CTFUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFUtilities.h; path = Plugin/CTFUtilities.h; sourceTree = ""; }; 845704590F47BC170017F3F4 /* CTFUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTFUtilities.m; path = Plugin/CTFUtilities.m; sourceTree = ""; }; A494CC2B0F9F2446007D5EEB /* ctf.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ctf.icns; path = Plugin/ctf.icns; sourceTree = ""; }; + A4DEFC760FF33F7400CCB6A8 /* CTFPreferencesDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFPreferencesDictionary.h; path = Plugin/CTFPreferencesDictionary.h; sourceTree = ""; }; + A4DEFC770FF33F7400CCB6A8 /* CTFPreferencesDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTFPreferencesDictionary.m; path = Plugin/CTFPreferencesDictionary.m; sourceTree = ""; }; + A4DEFC780FF33F7400CCB6A8 /* CTFUserDefaultsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFUserDefaultsController.h; path = Plugin/CTFUserDefaultsController.h; sourceTree = ""; }; + A4DEFC790FF33F7400CCB6A8 /* CTFUserDefaultsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTFUserDefaultsController.m; path = Plugin/CTFUserDefaultsController.m; sourceTree = ""; }; D9566C2C0F37EA0800358646 /* sifr2-addons.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "sifr2-addons.js"; sourceTree = ""; }; D9566C2D0F37EA0800358646 /* sifr3-addons.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "sifr3-addons.js"; sourceTree = ""; }; D9FFA7650F3941C1008A8708 /* ClickToFlash_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClickToFlash_Prefix.pch; path = Plugin/ClickToFlash_Prefix.pch; sourceTree = ""; }; @@ -193,6 +199,10 @@ children = ( 55EB703D0E04A84F0016593D /* Plugin.m */, 55EB703C0E04A84F0016593D /* Plugin.h */, + A4DEFC760FF33F7400CCB6A8 /* CTFPreferencesDictionary.h */, + A4DEFC770FF33F7400CCB6A8 /* CTFPreferencesDictionary.m */, + A4DEFC780FF33F7400CCB6A8 /* CTFUserDefaultsController.h */, + A4DEFC790FF33F7400CCB6A8 /* CTFUserDefaultsController.m */, 845704580F47BC170017F3F4 /* CTFUtilities.h */, 845704590F47BC170017F3F4 /* CTFUtilities.m */, 6953E4340F3EDE9D0014ECF7 /* CTFMenubarMenuController.m */, @@ -391,6 +401,8 @@ 8457045A0F47BC170017F3F4 /* CTFUtilities.m in Sources */, 79E2EB930F86AAD3005CF170 /* SparkleManager.m in Sources */, 0038DE240FC0CCF0007B54E9 /* MATrackingArea.m in Sources */, + A4DEFC7A0FF33F7400CCB6A8 /* CTFPreferencesDictionary.m in Sources */, + A4DEFC7B0FF33F7400CCB6A8 /* CTFUserDefaultsController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Plugin/CTFPreferencesDictionary.h b/Plugin/CTFPreferencesDictionary.h new file mode 100755 index 00000000..7bef80a7 --- /dev/null +++ b/Plugin/CTFPreferencesDictionary.h @@ -0,0 +1,17 @@ +// +// CTFPreferencesDictionary.h +// ClickToFlash +// +// Created by Simone Manganelli on 2009-05-25. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface CTFPreferencesDictionary : NSMutableDictionary { + NSMutableDictionary *realMutableDictionary; + BOOL hasInited; +} + +@end diff --git a/Plugin/CTFPreferencesDictionary.m b/Plugin/CTFPreferencesDictionary.m new file mode 100755 index 00000000..ea7e2acb --- /dev/null +++ b/Plugin/CTFPreferencesDictionary.m @@ -0,0 +1,92 @@ +// +// CTFPreferencesDictionary.m +// ClickToFlash +// +// Created by Simone Manganelli on 2009-05-25. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// +// the rationale for this class is so that we can monitor when +// defaults change, and update the *external* preference file accordingly. +// to do so, we need to monitor the mutable dictionary that represents the +// defaults. this class follows @bbum's suggestion at this URL: +// http://www.omnigroup.com/mailman/archive/macosx-dev/1999-April/007726.html + +#import "CTFPreferencesDictionary.h" + +static CTFPreferencesDictionary *sharedInstance = nil; + +@implementation CTFPreferencesDictionary + ++ (id)dictionaryWithDictionary:(NSDictionary *)otherDictionary; +{ + return [[CTFPreferencesDictionary alloc] initWithDictionary:otherDictionary]; +} + ++ (id)allocWithZone:(NSZone *)zone; +{ + if (sharedInstance) { + return [sharedInstance retain]; + } else { + return [super allocWithZone:zone]; + } +} + +- (id)init; +{ + if (! sharedInstance) { + if ((self = [super init])) { + realMutableDictionary = [[NSMutableDictionary alloc] init]; + hasInited = YES; + } + } + + return self; +} + +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +{ + if (! sharedInstance) { + if ((self = [super init])) { + realMutableDictionary = [[NSMutableDictionary dictionaryWithDictionary:otherDictionary] retain]; + hasInited = YES; + } + } else { + [sharedInstance setDictionary:otherDictionary]; + } + + return self; +} + +- (void)dealloc; +{ + [realMutableDictionary release]; + [super dealloc]; +} + +- (void)setObject:(id)object forKey:(id)key; +{ + [realMutableDictionary setObject:object forKey:key]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"ClickToFlashPluginDefaultsDidChange" object:self]; +} + +- (void)removeObjectForKey:(id)key; +{ + [realMutableDictionary removeObjectForKey:key]; +} + +- (id)objectForKey:(id)key; +{ + return [realMutableDictionary objectForKey:key]; +} + +- (NSUInteger)count; +{ + return [realMutableDictionary count]; +} + +- (NSEnumerator *)keyEnumerator; +{ + return [realMutableDictionary keyEnumerator]; +} + +@end diff --git a/Plugin/CTFUserDefaultsController.h b/Plugin/CTFUserDefaultsController.h new file mode 100755 index 00000000..aadbe036 --- /dev/null +++ b/Plugin/CTFUserDefaultsController.h @@ -0,0 +1,36 @@ +// +// CTFUserDefaultsController.h +// ClickToFlash +// +// Created by Simone Manganelli on 2009-05-23. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import +#import "CTFPreferencesDictionary.h" + + +@interface CTFUserDefaultsController : NSUserDefaultsController { + CTFPreferencesDictionary *userDefaultsDict; + BOOL hasInited; +} + ++ (CTFUserDefaultsController *)standardUserDefaults; +- (void)setUpExternalPrefsDictionary; + +- (void)pluginDefaultsDidChange:(NSNotification *)notification; +- (CTFPreferencesDictionary *)values; +- (CTFPreferencesDictionary *)dictionaryRepresentation; +- (void)setValues:(CTFPreferencesDictionary *)newUserDefaultsDict; + +- (id)objectForKey:(NSString *)defaultName; +- (void)setObject:(id)value forKey:(NSString *)defaultName; +- (int)integerForKey:(NSString *)defaultName; +- (void)setIntegerForKey:(int)value forKey:(NSString *)defaultName; +- (BOOL)boolForKey:(NSString *)defaultName; +- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; +- (NSArray *)arrayForKey:(NSString *)defaultName; +- (void)removeObjectForKey:(NSString *)defaultName; + + +@end diff --git a/Plugin/CTFUserDefaultsController.m b/Plugin/CTFUserDefaultsController.m new file mode 100755 index 00000000..672e46d8 --- /dev/null +++ b/Plugin/CTFUserDefaultsController.m @@ -0,0 +1,135 @@ +// +// CTFUserDefaultsController.m +// ClickToFlash +// +// Created by Simone Manganelli on 2009-05-23. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "CTFUserDefaultsController.h" + +static CTFUserDefaultsController *sharedInstance = nil; + +@implementation CTFUserDefaultsController + ++ (CTFUserDefaultsController *)standardUserDefaults; +{ + if (! sharedInstance) sharedInstance = [[self alloc] init]; + return sharedInstance; +} + ++ (id)allocWithZone:(NSZone *)zone; +{ + if (sharedInstance) { + return [sharedInstance retain]; + } else { + return [super allocWithZone:zone]; + } +} + +- (id)init; +{ + if (! sharedInstance) { + if ((self = [super init])) { + hasInited = YES; + } + } + + return self; +} + +- (void)dealloc; +{ + [userDefaultsDict release]; + [super dealloc]; +} + +- (void)setUpExternalPrefsDictionary; +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(pluginDefaultsDidChange:) + name:@"ClickToFlashPluginDefaultsDidChange" + object:nil]; + [self setValues:[CTFPreferencesDictionary dictionaryWithDictionary: + [[NSUserDefaults standardUserDefaults] persistentDomainForName:@"com.github.rentzsch.clicktoflash"]] + ]; +} + +- (CTFPreferencesDictionary *)values; +{ + // I have no idea why, but -init, -initWithDefaults:initialValues:, + // and +sharedUserDefaultsController all never seem to get called. Only + // -awakeFromNib gets called, and that's too late for bindings; + + // so instead, we just wait for the initial call to access values, + // and if that call detects that the user defaults dictionary hasn't + // been set up yet, it sets it up and *then* returns the values + + if (! userDefaultsDict) { + [self setUpExternalPrefsDictionary]; + } + return userDefaultsDict; +} + +- (CTFPreferencesDictionary *)dictionaryRepresentation; +{ + return [self values]; +} + +- (void)setValues:(CTFPreferencesDictionary *)newUserDefaultsDict; +{ + if (! userDefaultsDict) userDefaultsDict = [[CTFPreferencesDictionary alloc] init]; + [userDefaultsDict removeAllObjects]; + [userDefaultsDict addEntriesFromDictionary:newUserDefaultsDict]; +} + +- (void)pluginDefaultsDidChange:(NSNotification *)notification; +{ + [[NSUserDefaults standardUserDefaults] setPersistentDomain:userDefaultsDict + forName:@"com.github.rentzsch.clicktoflash"]; +} + +- (id)objectForKey:(NSString *)defaultName; +{ + return [[self values] objectForKey:defaultName]; +} + +- (void)setObject:(id)value forKey:(NSString *)defaultName; +{ + [[self values] setObject:value forKey:defaultName]; +} + +- (int)integerForKey:(NSString *)defaultName; +{ + return [[[self values] objectForKey:defaultName] intValue]; +} + +- (void)setIntegerForKey:(int)value forKey:(NSString *)defaultName; +{ + [[self values] setObject:[NSNumber numberWithInt:value] forKey:defaultName]; +} + +- (BOOL)boolForKey:(NSString *)defaultName; +{ + return [[[self values] objectForKey:defaultName] boolValue]; +} + +- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; +{ + [[self values] setObject:[NSNumber numberWithBool:value] forKey:defaultName]; +} + +- (NSArray *)arrayForKey:(NSString *)defaultName; +{ + id value = [[self values] objectForKey:defaultName]; + id valueToReturn = nil; + if ([[value className] isEqualToString:@"NSCFArray"]) valueToReturn = value; + return valueToReturn; +} + +- (void)removeObjectForKey:(NSString *)defaultName; +{ + [[self values] removeObjectForKey:defaultName]; +} + +@end diff --git a/Plugin/CTFWhitelist.m b/Plugin/CTFWhitelist.m index 4c6913d0..b8f23828 100644 --- a/Plugin/CTFWhitelist.m +++ b/Plugin/CTFWhitelist.m @@ -29,11 +29,14 @@ of this software and associated documentation files (the "Software"), to deal #import "CTFUtilities.h" #import "CTFMenubarMenuController.h" +#import "CTFUserDefaultsController.h" +#import "CTFPreferencesDictionary.h" + // NSNotification names static NSString *sCTFWhitelistAdditionMade = @"CTFWhitelistAdditionMade"; - // NSUserDefaults keys + // CTFUserDefaultsController keys static NSString *sHostSiteInfoDefaultsKey = @"ClickToFlash_siteInfo"; typedef enum { @@ -160,13 +163,13 @@ - (BOOL) _isHostWhitelisted - (BOOL) _isWhiteListedForHostString:(NSString *)hostString { - NSArray *hostWhitelist = [[NSUserDefaults standardUserDefaults] arrayForKey: sHostSiteInfoDefaultsKey]; + NSArray *hostWhitelist = [[CTFUserDefaultsController standardUserDefaults] arrayForKey: sHostSiteInfoDefaultsKey]; return hostWhitelist && itemForSite(hostWhitelist, hostString) != nil; } - (NSMutableArray *) _mutableSiteInfo { - NSMutableArray *hostWhitelist = [[[[NSUserDefaults standardUserDefaults] arrayForKey: sHostSiteInfoDefaultsKey] mutableCopy] autorelease]; + NSMutableArray *hostWhitelist = [[[[CTFUserDefaultsController standardUserDefaults] arrayForKey: sHostSiteInfoDefaultsKey] mutableCopy] autorelease]; if (hostWhitelist == nil) { hostWhitelist = [NSMutableArray array]; } @@ -177,7 +180,7 @@ - (void) _addHostToWhitelist { NSMutableArray *siteInfo = [self _mutableSiteInfo]; [siteInfo addObject: whitelistItemForSite([self host])]; - [[NSUserDefaults standardUserDefaults] setObject: siteInfo forKey: sHostSiteInfoDefaultsKey]; + [[CTFUserDefaultsController standardUserDefaults] setObject: siteInfo forKey: sHostSiteInfoDefaultsKey]; [[NSNotificationCenter defaultCenter] postNotificationName: sCTFWhitelistAdditionMade object: self]; } @@ -188,7 +191,7 @@ - (void) _removeHostFromWhitelist if(foundIndex != NSNotFound) { [siteInfo removeObjectAtIndex: foundIndex]; - [[NSUserDefaults standardUserDefaults] setObject: siteInfo forKey: sHostSiteInfoDefaultsKey]; + [[CTFUserDefaultsController standardUserDefaults] setObject: siteInfo forKey: sHostSiteInfoDefaultsKey]; } } diff --git a/Plugin/CTFWhitelistWindowController.h b/Plugin/CTFWhitelistWindowController.h index 808bb619..4f5cdbe8 100755 --- a/Plugin/CTFWhitelistWindowController.h +++ b/Plugin/CTFWhitelistWindowController.h @@ -5,9 +5,20 @@ extern NSString* kCTFCheckForUpdates; @interface CTFWhitelistWindowController : NSWindowController { IBOutlet NSArrayController *_controller; IBOutlet NSButton *_checkNowButton; + + IBOutlet NSPanel *confirmUninstallSheet; + IBOutlet NSPanel *successfulUninstallationSheet; + IBOutlet NSPanel *failedUninstallationSheet; } - (IBAction)checkForUpdates:(id)sender; +- (IBAction)uninstallClickToFlash:(id)sender; + +- (IBAction)cancelUninstall:(id)sender; +- (IBAction)approveUninstall:(id)sender; + +- (IBAction)dismissSuccessSheet:(id)sender; +- (IBAction)dismissFailureSheet:(id)sender; @end diff --git a/Plugin/CTFWhitelistWindowController.m b/Plugin/CTFWhitelistWindowController.m index e49841d0..f56ff678 100755 --- a/Plugin/CTFWhitelistWindowController.m +++ b/Plugin/CTFWhitelistWindowController.m @@ -35,4 +35,98 @@ - (NSString *)versionString return [CTFBundle objectForInfoDictionaryKey: @"CFBundleShortVersionString"]; } +- (IBAction)uninstallClickToFlash:(id)sender; +{ + [NSApp beginSheet:confirmUninstallSheet + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:nil]; +} + +- (IBAction)cancelUninstall:(id)sender; +{ + [confirmUninstallSheet orderOut:sender]; + + [NSApp endSheet:confirmUninstallSheet returnCode:0]; +} + +- (IBAction)approveUninstall:(id)sender; +{ + [confirmUninstallSheet orderOut:sender]; + + [NSApp endSheet:confirmUninstallSheet returnCode:1]; +} + +- (void)sheetDidEnd:(NSWindow *)sheet + returnCode:(int)returnCode + contextInfo:(void *)contextInfo; +{ + if (returnCode == 1) { + NSString *userPluginPath = [@"~/Library/Internet Plug-ins/ClickToFlash.webplugin" stringByExpandingTildeInPath]; + BOOL isDirectory = NO; + BOOL userPluginExists = [[NSFileManager defaultManager] fileExistsAtPath:userPluginPath + isDirectory:&isDirectory]; + BOOL succeeded = NO; + if (userPluginExists && isDirectory) { + // we'll move the plugin to the trash, instead of just obstinately + // deleting it + succeeded = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation + source:[@"~/Library/Internet Plug-ins/" stringByExpandingTildeInPath] + destination:nil + files:[NSArray arrayWithObject:@"ClickToFlash.webplugin"] + tag:nil]; + } + + if (succeeded) { + [NSApp beginSheet:successfulUninstallationSheet + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:nil]; + } else { + // there are three ways to get here: + + // 1. either userPluginExists equals NO, in which case the plugin is + // installed for all users and we can't guarantee that we can + // uninstall it, so we'll just fail + + // 2. an item exists at the correct path, but it's a file not a + // folder, so it's not ClickToFlash + + // 3. the plugin exists, but for some reason we couldn't move + // it to the trash + + [NSApp beginSheet:failedUninstallationSheet + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(resultSheetDidEnd:returnCode:contextInfo:) + contextInfo:nil]; + } + } else { + // uninstallation was cancelled + } +} + +- (IBAction)dismissSuccessSheet:(id)sender; +{ + [successfulUninstallationSheet orderOut:sender]; + + [NSApp endSheet:successfulUninstallationSheet returnCode:0]; +} + +- (IBAction)dismissFailureSheet:(id)sender; +{ + [failedUninstallationSheet orderOut:sender]; + + [NSApp endSheet:failedUninstallationSheet returnCode:0]; +} + +- (void)returnSheetDidEnd:(NSWindow *)sheet + returnCode:(int)returnCode + contextInfo:(void *)contextInfo; +{ + // nothing to see here! +} + @end diff --git a/Plugin/CTFsIFRSupport.m b/Plugin/CTFsIFRSupport.m index 5ded0e8e..cc52f8b1 100644 --- a/Plugin/CTFsIFRSupport.m +++ b/Plugin/CTFsIFRSupport.m @@ -26,13 +26,16 @@ of this software and associated documentation files (the "Software"), to deal #import "CTFsIFRSupport.h" +#import "CTFUserDefaultsController.h" +#import "CTFPreferencesDictionary.h" + typedef enum { CTFSifrModeDoNothing = 0, CTFSifrModeAutoLoadSifr = 1, CTFSifrModeDeSifr = 2 } CTFSifrMode; -static NSString *sSifrModeDefaultsKey = @"ClickToFlash_sifrMode"; +static NSString *sSifrModeDefaultsKey = @"sifrMode"; static NSString *sSifr2Test = @"sIFR != null && typeof sIFR == \"function\""; static NSString *sSifr3Test = @"sIFR != null && typeof sIFR == \"object\""; @@ -61,7 +64,7 @@ - (NSUInteger) _sifrVersionInstalled - (BOOL) _shouldDeSIFR { - if ([[NSUserDefaults standardUserDefaults] integerForKey: sSifrModeDefaultsKey] == CTFSifrModeDeSifr) { + if ([[CTFUserDefaultsController standardUserDefaults] integerForKey: sSifrModeDefaultsKey] == CTFSifrModeDeSifr) { _sifrVersion = [self _sifrVersionInstalled]; if( _sifrVersion != 0 ) @@ -73,7 +76,7 @@ - (BOOL) _shouldDeSIFR - (BOOL) _shouldAutoLoadSIFR { - return [[NSUserDefaults standardUserDefaults] integerForKey: sSifrModeDefaultsKey] == CTFSifrModeAutoLoadSifr; + return [[CTFUserDefaultsController standardUserDefaults] integerForKey: sSifrModeDefaultsKey] == CTFSifrModeAutoLoadSifr; } - (void) _disableSIFR diff --git a/Plugin/English.lproj/WhitelistPanel.xib b/Plugin/English.lproj/WhitelistPanel.xib index eb44e13c..74653e3b 100755 --- a/Plugin/English.lproj/WhitelistPanel.xib +++ b/Plugin/English.lproj/WhitelistPanel.xib @@ -1,14 +1,13 @@ - 1050 - 9G55 + 1040 + 9J61 677 - 949.43 + 949.46 353.00 YES - YES @@ -38,15 +37,15 @@ 15 2 - {{80, 265}, {527, 438}} + {{80, 209}, {527, 494}} -534248448 Q2xpY2sgdG8gRmxhc2gg4oCUIFNldHRpbmdzA NSPanel {3.40282e+38, 3.40282e+38} - {420, 350} + {420, 400} - + 274 YES @@ -204,7 +203,7 @@ - {{20, 58}, {487, 169}} + {{20, 69}, {487, 169}} 530 @@ -218,7 +217,7 @@ 292 - {{48, 30}, {29, 26}} + {{48, 41}, {29, 26}} YES @@ -242,7 +241,7 @@ 292 - {{20, 30}, {29, 26}} + {{20, 41}, {29, 26}} YES @@ -262,7 +261,7 @@ 289 - {{227, 31}, {283, 17}} + {{227, 42}, {283, 17}} YES @@ -288,7 +287,7 @@ 268 - {{93, 149}, {286, 18}} + {{93, 194}, {286, 18}} YES @@ -319,7 +318,7 @@ 268 - {{93, 129}, {286, 18}} + {{93, 174}, {286, 18}} YES @@ -341,7 +340,7 @@ 268 - {{17, 170}, {67, 17}} + {{17, 215}, {67, 17}} YES @@ -357,7 +356,7 @@ 268 - {{93, 58}, {285, 58}} + {{93, 103}, {285, 58}} YES 3 @@ -628,7 +627,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{17, 99}, {67, 17}} + {{17, 144}, {67, 17}} YES @@ -644,7 +643,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{17, 28}, {67, 17}} + {{17, 73}, {67, 17}} YES @@ -657,10 +656,26 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + + 268 + {{17, 20}, {67, 17}} + + YES + + 68288064 + 71304192 + Uninstall: + + + + + + 268 - {{93, 27}, {287, 18}} + {{93, 72}, {287, 18}} YES @@ -682,7 +697,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{117, -3}, {86, 28}} + {{117, 42}, {86, 28}} YES @@ -702,7 +717,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{93, 169}, {286, 18}} + {{93, 214}, {286, 18}} YES @@ -721,21 +736,41 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 25 + + + 268 + {{88, 13}, {144, 28}} + + YES + + 67239424 + 134348800 + Uninstall ClickToFlash + + + -2038284033 + 129 + + + 200 + 25 + + - {{65, 235}, {397, 207}} + {{65, 246}, {397, 252}} NSView 289 - {{471, 9}, {39, 14}} + {{467, 20}, {43, 14}} YES 68288064 71435264 - 1.4fc6 + version @@ -743,17 +778,13 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - {527, 438} - + {527, 494} {{0, 0}, {1280, 778}} - {420, 372} + {420, 422} {3.40282e+38, 3.40282e+38} ClickToFlash_settingsWindow - - YES - YES @@ -769,6 +800,385 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES YES + + YES + + + + YES + pluginEnabled + useYouTubeH264 + autoLoadInvisibleViews + sifrMode + checkForUpdatesOnFirstLoad + siteInfo + + YES + + + 1 + 2 + {{108, 592}, {461, 124}} + 1886912512 + Uninstall ClickToFlash Confirmation + NSPanel + + View + + {3.40282e+38, 3.40282e+38} + {213, 107} + + + 256 + + YES + + + 256 + {{352, 14}, {95, 32}} + + YES + + 67239424 + 137887744 + Uninstall + + + -2038284033 + 1 + + Helvetica + 1.300000e+01 + 16 + + + + + + + + 200 + 25 + + + + + 256 + {{268, 14}, {84, 32}} + + YES + + 67239424 + 137887744 + Cancel + + + -2038284033 + 1 + + + Gw + 200 + 25 + + + + + 256 + + YES + + YES + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + + {{20, 20}, {84, 84}} + + YES + + 130560 + 33554432 + + NSImage + ctf + + 0 + 0 + 0 + NO + + YES + + + + 256 + {{109, 84}, {335, 20}} + + YES + + 67239424 + 4194304 + Are you sure you want to uninstall ClickToFlash? + + LucidaGrande-Bold + 1.300000e+01 + 2072 + + + + + + + + + 256 + {{109, 62}, {335, 14}} + + YES + + 67239424 + 4194304 + The ClickToFlash plugin will be uninstalled only for this user. + + + + + + + + {461, 124} + + {{0, 0}, {1280, 778}} + {213, 129} + {3.40282e+38, 3.40282e+38} + + + 1 + 2 + {{108, 566}, {461, 150}} + 1886912512 + ClickToFlash Uninstallation Failed + NSPanel + + View + + {3.40282e+38, 3.40282e+38} + {213, 107} + + + 256 + + YES + + + 256 + {{352, 12}, {95, 32}} + + YES + + 67239424 + 137887744 + OK + + + -2038284033 + 1 + + + + + + + + 200 + 25 + + + + + 256 + + YES + + YES + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + + {{20, 46}, {84, 84}} + + YES + + 130560 + 33554432 + + 0 + 0 + 0 + NO + + YES + + + + 256 + {{109, 110}, {335, 20}} + + YES + + 67239424 + 4194304 + ClickToFlash uninstallation failed. + + + + + + + + + 256 + {{109, 60}, {335, 42}} + + YES + + 67239424 + 4194304 + Q2xpY2tUb0ZsYXNoIG1heSBiZSBpbnN0YWxsZWQgZm9yIGFsbCB1c2Vycy4gIE1hbnVhbGx5IGRlbGV0 +ZSAiQ2xpY2tUb0ZsYXNoLndlYnBsdWdpbiIgZnJvbSAvTGlicmFyeS9JbnRlcm5ldCBQbHVnLWlucy8g +dG8gdW5pbnN0YWxsIENsaWNrVG9GbGFzaC4 + + + + + + + + {461, 150} + + {{0, 0}, {1280, 778}} + {213, 129} + {3.40282e+38, 3.40282e+38} + + + 1 + 2 + {{108, 592}, {461, 124}} + 1886912512 + ClickToFlash Uninstallation Succeeded + NSPanel + + View + + {3.40282e+38, 3.40282e+38} + {213, 107} + + + 256 + + YES + + + 256 + {{352, 12}, {95, 32}} + + YES + + 67239424 + 137887744 + OK + + + -2038284033 + 1 + + + + + + + + 200 + 25 + + + + + 256 + + YES + + YES + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + + {{20, 20}, {84, 84}} + + YES + + 130560 + 33554432 + + 0 + 0 + 0 + NO + + YES + + + + 256 + {{109, 84}, {335, 20}} + + YES + + 67239424 + 4194304 + ClickToFlash successfully uninstalled. + + + + + + + + + 256 + {{109, 34}, {335, 42}} + + YES + + 67239424 + 4194304 + You must restart this application for the changes to take effect. + + + + + + + + {461, 124} + + {{0, 0}, {1280, 778}} + {213, 129} + {3.40282e+38, 3.40282e+38} + @@ -805,38 +1215,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 24 - - - value: values.ClickToFlash_useYouTubeH264 - - - - - - value: values.ClickToFlash_useYouTubeH264 - value - values.ClickToFlash_useYouTubeH264 - 2 - - - 48 - - - - selectedTag: values.ClickToFlash_sifrMode - - - - - - selectedTag: values.ClickToFlash_sifrMode - selectedTag - values.ClickToFlash_sifrMode - 2 - - - 112 - add: @@ -845,26 +1223,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 115 - - - contentArray: values.ClickToFlash_siteInfo - - - - - - contentArray: values.ClickToFlash_siteInfo - contentArray - values.ClickToFlash_siteInfo - - NSHandlesContentAsCompoundValue - - - 2 - - - 127 - value: arrangedObjects.site @@ -894,89 +1252,205 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 130 + + + checkForUpdates: + + + + 146 + + + + _checkNowButton + + + + 148 + - value: values.ClickToFlash_autoLoadInvisibleViews + value: versionString + + + + + + value: versionString + value + versionString + + NSAllowsEditingMultipleValuesSelection + + + 2 + + + 165 + + + + value: values.pluginEnabled + + + + + + value: values.pluginEnabled + value + values.pluginEnabled + 2 + + + 178 + + + + value: values.useYouTubeH264 + + + + + + value: values.useYouTubeH264 + value + values.useYouTubeH264 + 2 + + + 179 + + + + value: values.autoLoadInvisibleViews - + - - value: values.ClickToFlash_autoLoadInvisibleViews + + value: values.autoLoadInvisibleViews value - values.ClickToFlash_autoLoadInvisibleViews + values.autoLoadInvisibleViews 2 - 136 + 180 - - checkForUpdates: - - + + selectedTag: values.sifrMode + + + + + + selectedTag: values.sifrMode + selectedTag + values.sifrMode + 2 + - 146 + 181 - value: values.ClickToFlash_checkForUpdatesOnFirstLoad + value: values.checkForUpdatesOnFirstLoad - + - - value: values.ClickToFlash_checkForUpdatesOnFirstLoad + + value: values.checkForUpdatesOnFirstLoad value - values.ClickToFlash_checkForUpdatesOnFirstLoad + values.checkForUpdatesOnFirstLoad 2 - 147 + 182 + + + + contentArray: values.siteInfo + + + + + + contentArray: values.siteInfo + contentArray + values.siteInfo + + NSHandlesContentAsCompoundValue + + + 2 + + + 183 - _checkNowButton + confirmUninstallSheet - + - 148 + 210 - - value: values.ClickToFlash_pluginEnabled - - - - - - value: values.ClickToFlash_pluginEnabled - value - values.ClickToFlash_pluginEnabled - 2 - + + approveUninstall: + + + + 211 + + + + cancelUninstall: + + + + 212 + + + + failedUninstallationSheet + + + + 235 + + + + successfulUninstallationSheet + + + + 236 + + + + dismissSuccessSheet: + + - 155 + 237 - - value: versionString - - - - - - value: versionString - value - versionString - - NSAllowsEditingMultipleValuesSelection - - - 2 - + + dismissFailureSheet: + + - 165 + 238 + + + + uninstallClickToFlash: + + + + 239 @@ -1023,10 +1497,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES + - @@ -1037,11 +1511,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA Whitelisted Hosts - - 7 - - - 9 @@ -1148,6 +1617,8 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + @@ -1309,6 +1780,294 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + 7 + + + + + 170 + + + Plugin Defaults + + + 186 + + + YES + + + + + + 187 + + + + + 190 + + + YES + + + + + + 191 + + + + + 194 + + + YES + + + + Uninstall Confirm + + + 195 + + + YES + + + + + + + + + + 196 + + + YES + + + + + + 197 + + + YES + + + + + + 199 + + + YES + + + + + + 200 + + + YES + + + + + + 201 + + + YES + + + + + + 202 + + + + + 203 + + + + + 204 + + + + + 206 + + + + + 207 + + + + + 213 + + + YES + + + + Uninstall Failure + + + 214 + + + YES + + + + + + + + + 216 + + + YES + + + + + + 217 + + + YES + + + + + + 218 + + + YES + + + + + + 219 + + + YES + + + + + + 220 + + + + + 221 + + + + + 222 + + + + + 223 + + + + + 225 + + + YES + + + + Uninstall Success + + + 226 + + + YES + + + + + + + + + 227 + + + YES + + + + + + 228 + + + YES + + + + + + 229 + + + YES + + + + + + 230 + + + YES + + + + + + 231 + + + + + 232 + + + + + 233 + + + + + 234 + + + @@ -1319,7 +2078,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA -2.IBPluginDependency -3.IBPluginDependency 1.IBEditorWindowLastContentRect - 1.IBPluginDependency 1.IBViewEditorWindowController.showingLayoutRectangles 1.IBWindowTemplateEditedContentRect 1.NSWindowTemplate.visibleAtLaunch @@ -1333,6 +2091,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 102.IBPluginDependency 103.IBPluginDependency 104.IBPluginDependency + 105.IBPluginDependency 106.IBAttributePlaceholdersKey 106.IBPluginDependency 107.IBPluginDependency @@ -1359,9 +2118,78 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 156.IBPluginDependency 157.IBPluginDependency 17.IBPluginDependency + 170.CustomClassName + 170.IBPluginDependency + 186.IBPluginDependency + 187.IBPluginDependency + 190.IBPluginDependency + 191.IBPluginDependency + 194.IBEditorWindowLastContentRect + 194.IBViewEditorWindowController.showingLayoutRectangles + 194.IBWindowTemplateEditedContentRect + 194.ImportedFromIB2 + 194.windowTemplate.hasMinSize + 194.windowTemplate.minSize + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 2.IBPluginDependency 20.IBPluginDependency + 200.IBPluginDependency + 200.ImportedFromIB2 + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 203.IBPluginDependency + 204.IBPluginDependency + 206.IBPluginDependency + 207.IBPluginDependency 21.IBPluginDependency + 213.IBEditorWindowLastContentRect + 213.IBViewEditorWindowController.showingLayoutRectangles + 213.IBWindowTemplateEditedContentRect + 213.ImportedFromIB2 + 213.windowTemplate.hasMinSize + 213.windowTemplate.minSize + 214.IBPluginDependency + 214.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBPluginDependency + 221.IBPluginDependency + 222.IBPluginDependency + 223.IBPluginDependency + 225.IBEditorWindowLastContentRect + 225.IBViewEditorWindowController.showingLayoutRectangles + 225.IBWindowTemplateEditedContentRect + 225.ImportedFromIB2 + 225.windowTemplate.hasMinSize + 225.windowTemplate.minSize + 226.IBPluginDependency + 226.ImportedFromIB2 + 227.IBPluginDependency + 227.ImportedFromIB2 + 228.IBPluginDependency + 228.ImportedFromIB2 + 229.IBPluginDependency + 229.ImportedFromIB2 + 230.IBPluginDependency + 230.ImportedFromIB2 + 231.IBPluginDependency + 232.IBPluginDependency + 233.IBPluginDependency + 234.IBPluginDependency 31.IBPluginDependency 32.IBPluginDependency 36.IBAttributePlaceholdersKey @@ -1370,6 +2198,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 39.IBPluginDependency 4.IBPluginDependency 41.IBPluginDependency + 42.IBPluginDependency + 7.CustomClassName + 7.IBPluginDependency 9.IBPluginDependency @@ -1377,15 +2208,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilderKit com.apple.InterfaceBuilderKit - {{40, 279}, {527, 438}} - com.apple.InterfaceBuilder.CocoaPlugin + {{12, 251}, {527, 494}} - {{40, 279}, {527, 438}} - + {{12, 251}, {527, 494}} + {196, 240} {{202, 428}, {480, 270}} - - {420, 350} + + {420, 400} com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -1399,6 +2229,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -1460,6 +2291,75 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + CTFUserDefaultsController + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{97, 461}, {461, 124}} + + {{97, 461}, {461, 124}} + + + {213, 107} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{105, 287}, {461, 150}} + + {{105, 287}, {461, 150}} + + + {213, 107} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{132, 289}, {461, 124}} + + {{132, 289}, {461, 124}} + + + {213, 107} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1479,6 +2379,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + CTFUserDefaultsController + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin @@ -1501,17 +2404,42 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - 165 + 239 YES + + CTFUserDefaultsController + NSUserDefaultsController + + IBProjectSource + Plugin/CTFUserDefaultsController.h + + CTFWhitelistWindowController NSWindowController - checkForUpdates: - id + YES + + YES + approveUninstall: + cancelUninstall: + checkForUpdates: + dismissFailureSheet: + dismissSuccessSheet: + uninstallClickToFlash: + + + YES + id + id + id + id + id + id + YES @@ -1519,11 +2447,17 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES _checkNowButton _controller + confirmUninstallSheet + failedUninstallationSheet + successfulUninstallationSheet YES NSButton NSArrayController + NSPanel + NSPanel + NSPanel diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h index 7c663ddb..c7ba6029 100755 --- a/Plugin/Plugin.h +++ b/Plugin/Plugin.h @@ -52,6 +52,8 @@ THE SOFTWARE. + (NSView *)plugInViewWithArguments:(NSDictionary *)arguments; - (id) initWithArguments:(NSDictionary *)arguments; +- (void)_migratePrefsToExternalFile; +- (void) _addApplicationWhitelistToPrefsFile; - (DOMElement *)container; - (void)setContainer:(DOMElement *)newValue; diff --git a/Plugin/Plugin.m b/Plugin/Plugin.m index 8b8edd7f..51129d43 100755 --- a/Plugin/Plugin.m +++ b/Plugin/Plugin.m @@ -25,6 +25,8 @@ of this software and associated documentation files (the "Software"), to deal */ #import "Plugin.h" +#import "CTFUserDefaultsController.h" +#import "CTFPreferencesDictionary.h" #import "MATrackingArea.h" #import "CTFMenubarMenuController.h" @@ -40,10 +42,11 @@ of this software and associated documentation files (the "Software"), to deal static NSString *sFlashOldMIMEType = @"application/x-shockwave-flash"; static NSString *sFlashNewMIMEType = @"application/futuresplash"; - // NSUserDefaults keys -static NSString *sUseYouTubeH264DefaultsKey = @"ClickToFlash_useYouTubeH264"; -static NSString *sAutoLoadInvisibleFlashViewsKey = @"ClickToFlash_autoLoadInvisibleViews"; -static NSString *sPluginEnabled = @"ClickToFlash_pluginEnabled"; + // CTFUserDefaultsController keys +static NSString *sUseYouTubeH264DefaultsKey = @"useYouTubeH264"; +static NSString *sAutoLoadInvisibleFlashViewsKey = @"autoLoadInvisibleViews"; +static NSString *sPluginEnabled = @"pluginEnabled"; +static NSString *sApplicationWhitelist = @"applicationWhitelist"; BOOL usingMATrackingArea = NO; @@ -101,21 +104,20 @@ - (id) initWithArguments:(NSDictionary *)arguments { self = [super init]; if (self) { + [[NSUserDefaults standardUserDefaults] addSuiteNamed:@"com.github.rentzsch.clicktoflash"]; SparkleManager *sharedSparkleManager = [SparkleManager sharedManager]; NSWorkspace *sharedWorkspace = [NSWorkspace sharedWorkspace]; NSString *pathToRelaunch = [sharedWorkspace absolutePathForAppBundleWithIdentifier:[self launchedAppBundleIdentifier]]; [sharedSparkleManager setPathToRelaunch:pathToRelaunch]; [sharedSparkleManager startAutomaticallyCheckingForUpdates]; - - if (![[NSUserDefaults standardUserDefaults] objectForKey:sAutoLoadInvisibleFlashViewsKey]) { + if (![[CTFUserDefaultsController standardUserDefaults] objectForKey:sAutoLoadInvisibleFlashViewsKey]) { // Default to auto-loading invisible flash views. - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:sAutoLoadInvisibleFlashViewsKey]; + [[CTFUserDefaultsController standardUserDefaults] setBool:YES forKey:sAutoLoadInvisibleFlashViewsKey]; } - if (![[NSUserDefaults standardUserDefaults] objectForKey:sPluginEnabled]) { + if (![[CTFUserDefaultsController standardUserDefaults] objectForKey:sPluginEnabled]) { // Default to enable the plugin - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:sPluginEnabled]; + [[CTFUserDefaultsController standardUserDefaults] setBool:YES forKey:sPluginEnabled]; } - [self setLaunchedAppBundleIdentifier:[self launchedAppBundleIdentifier]]; [self setWebView:[[[arguments objectForKey:WebPlugInContainerKey] webFrame] webView]]; @@ -123,6 +125,8 @@ - (id) initWithArguments:(NSDictionary *)arguments [self setContainer:[arguments objectForKey:WebPlugInContainingElementKey]]; [self _migrateWhitelist]; + [self _migratePrefsToExternalFile]; + [self _addApplicationWhitelistToPrefsFile]; // Get URL @@ -187,7 +191,11 @@ - (id) initWithArguments:(NSDictionary *)arguments // check whether plugin is disabled, load all content as normal if so - if ( ![ [ NSUserDefaults standardUserDefaults ] boolForKey: sPluginEnabled ] ) { + CTFUserDefaultsController *standardUserDefaults = [CTFUserDefaultsController standardUserDefaults]; + BOOL pluginEnabled = [standardUserDefaults boolForKey:sPluginEnabled ]; + NSString *hostAppBundleID = [[NSBundle mainBundle] bundleIdentifier]; + BOOL hostAppIsInWhitelist = [[standardUserDefaults arrayForKey:sApplicationWhitelist] containsObject:hostAppBundleID]; + if ( (! pluginEnabled) || (hostAppIsInWhitelist) ) { _isLoadingFromWhitelist = YES; [self _convertTypesForContainer]; return self; @@ -216,7 +224,7 @@ - (id) initWithArguments:(NSDictionary *)arguments } } - if ( [ [ NSUserDefaults standardUserDefaults ] boolForKey: sAutoLoadInvisibleFlashViewsKey ] + if ( [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sAutoLoadInvisibleFlashViewsKey ] && [ self isConsideredInvisible ] ) { // auto-loading is on and this view meets the size constraints _isLoadingFromWhitelist = YES; @@ -356,6 +364,67 @@ - (void) dealloc [super dealloc]; } +- (void) _migratePrefsToExternalFile +{ + NSArray *parasiticDefaultsNameArray = [NSArray arrayWithObjects:@"ClickToFlash_pluginEnabled", + @"ClickToFlash_useYouTubeH264", + @"ClickToFlash_autoLoadInvisibleViews", + @"ClickToFlash_sifrMode", + @"ClickToFlash_checkForUpdatesOnFirstLoad", + @"ClickToFlash_siteInfo", + nil]; + + NSArray *externalDefaultsNameArray = [NSArray arrayWithObjects:@"pluginEnabled", + @"useYouTubeH264", + @"autoLoadInvisibleViews", + @"sifrMode", + @"checkForUpdatesOnFirstLoad", + @"siteInfo", + nil]; + + NSMutableDictionary *externalFileDefaults = [[CTFUserDefaultsController standardUserDefaults] dictionaryRepresentation]; + + unsigned int i; + for (i = 0; i < [parasiticDefaultsNameArray count]; i++) { + NSString *currentParasiticDefault = [parasiticDefaultsNameArray objectAtIndex:i]; + id prefValue = [[NSUserDefaults standardUserDefaults] objectForKey:currentParasiticDefault]; + if (prefValue) { + NSString *externalPrefDefaultName = [externalDefaultsNameArray objectAtIndex:i]; + id existingExternalPref = [[CTFUserDefaultsController standardUserDefaults] objectForKey:externalPrefDefaultName]; + if (! existingExternalPref) { + // don't overwrite existing external preferences + [externalFileDefaults setObject:prefValue forKey:externalPrefDefaultName]; + } else { + if ([currentParasiticDefault isEqualToString:@"ClickToFlash_siteInfo"]) { + // merge the arrays of whitelisted sites, in case they're not identical + + NSMutableArray *combinedWhitelist = [NSMutableArray arrayWithArray:prefValue]; + [combinedWhitelist addObjectsFromArray:existingExternalPref]; + [externalFileDefaults setObject:combinedWhitelist forKey:externalPrefDefaultName]; + } + } + // eliminate the parasitic default, regardless of whether we transferred them or not + [[NSUserDefaults standardUserDefaults] removeObjectForKey:currentParasiticDefault]; + } + } +} + +- (void) _addApplicationWhitelistToPrefsFile +{ + CTFUserDefaultsController *standardUserDefaults = [CTFUserDefaultsController standardUserDefaults]; + NSArray *applicationWhitelist = [standardUserDefaults arrayForKey:sApplicationWhitelist]; + if (! applicationWhitelist) { + // add the default list of apps to the whitelist + NSArray *defaultWhitelist = [NSArray arrayWithObjects:@"com.hulu.HuluDesktop", + @"com.echoone.iSwiff", + @"com.riverfold.WiiTransfer", + @"com.bitcartel.pandorajam", + @"com.adobe.flexbuilder", + nil]; + [standardUserDefaults setObject:defaultWhitelist forKey:sApplicationWhitelist]; + } +} + - (void) drawRect:(NSRect)rect { if(!_isLoadingFromWhitelist) @@ -489,8 +558,11 @@ - (NSMenu*) menuForEvent: (NSEvent*) event action: @selector( loadH264: ) keyEquivalent: @"" atIndex: 1]; [[self menu] insertItemWithTitle: NSLocalizedString( @"Download H.264", "Download H.264 menu item" ) action: @selector( downloadH264: ) keyEquivalent: @"" atIndex: 2]; + [[self menu] insertItemWithTitle: NSLocalizedString( @"Play Fullscreen in QuickTime Player", "Open Fullscreen in QT Player menu item" ) + action: @selector( openFullscreenInQTPlayer: ) keyEquivalent: @"" atIndex: 3]; [[[self menu] itemAtIndex: 1] setTarget: self]; [[[self menu] itemAtIndex: 2] setTarget: self]; + [[[self menu] itemAtIndex: 3] setTarget: self]; } else if (_fromYouTube) { // has no H.264 version but is from YouTube; it's an embedded view! @@ -878,8 +950,8 @@ - (BOOL) _hasH264Version - (BOOL) _useH264Version { return [ self _hasH264Version ] - && [ [ NSUserDefaults standardUserDefaults ] boolForKey: sUseYouTubeH264DefaultsKey ] - && [ [ NSUserDefaults standardUserDefaults ] boolForKey: sPluginEnabled ]; + && [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sUseYouTubeH264DefaultsKey ] + && [ [ CTFUserDefaultsController standardUserDefaults ] boolForKey: sPluginEnabled ]; } - (void) _convertElementForMP4: (DOMElement*) element @@ -990,6 +1062,22 @@ - (IBAction)loadYouTubePage:(id)sender launchIdentifiers:nil]; } +- (IBAction)openFullscreenInQTPlayer:(id)sender; +{ + NSString* video_id = [self videoId]; + NSString* video_hash = [ self _videoHash ]; + + NSString* src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@", + video_id, video_hash ]; + + NSString *scriptSource = [NSString stringWithFormat: + @"tell application \"QuickTime Player\"\nactivate\ngetURL \"%@\"\nrepeat while (display state of front document is not presentation)\ndelay 1\npresent front document scale screen\nend repeat\nrepeat while (playing of front document is false)\ndelay 1\nplay front document\nend repeat\nend tell",src]; + NSLog(@"%@",scriptSource); + NSAppleScript *openInQTPlayerScript = [[NSAppleScript alloc] initWithSource:scriptSource]; + [openInQTPlayerScript executeAndReturnError:nil]; + [openInQTPlayerScript release]; +} + #pragma mark - #pragma mark DOM Conversion diff --git a/Plugin/SparkleManager.m b/Plugin/SparkleManager.m index 87c784f7..ed0c0f29 100644 --- a/Plugin/SparkleManager.m +++ b/Plugin/SparkleManager.m @@ -27,8 +27,11 @@ of this software and associated documentation files (the "Software"), to deal #import "SparkleManager.h" #import +#import "CTFUserDefaultsController.h" +#import "CTFPreferencesDictionary.h" + // NSUserDefaults keys -static NSString *sAutomaticallyCheckForUpdates = @"ClickToFlash_checkForUpdatesOnFirstLoad"; +static NSString *sAutomaticallyCheckForUpdates = @"checkForUpdatesOnFirstLoad"; @implementation SparkleManager @@ -99,11 +102,11 @@ - (SUUpdater*)_updater { } - (void)startAutomaticallyCheckingForUpdates { - if (![[NSUserDefaults standardUserDefaults] objectForKey:sAutomaticallyCheckForUpdates]) { + if (![[CTFUserDefaultsController standardUserDefaults] objectForKey:sAutomaticallyCheckForUpdates]) { // If the key isn't set yet, default to YES, automatically check for updates. - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:sAutomaticallyCheckForUpdates]; + [[CTFUserDefaultsController standardUserDefaults] setBool:YES forKey:sAutomaticallyCheckForUpdates]; } - if ([[NSUserDefaults standardUserDefaults] boolForKey:sAutomaticallyCheckForUpdates]) { + if ([[CTFUserDefaultsController standardUserDefaults] boolForKey:sAutomaticallyCheckForUpdates]) { static BOOL checkedForUpdate = NO; if (!checkedForUpdate) { checkedForUpdate = YES; diff --git a/README.markdown b/README.markdown index 26e83b30..8525ca20 100644 --- a/README.markdown +++ b/README.markdown @@ -20,6 +20,8 @@ Please [report bugs and request features](http://rentzsch.lighthouseapp.com/proj Want to chip in? [Here's what needs to be done](http://rentzsch.lighthouseapp.com/projects/24342-clicktoflash/tickets?q=not-tagged%3Abrokensite+state%3Aopen&filter=). +To uninstall ClickToFlash: for versions 1.5b4 and later, go to the Settings window and click the "Uninstall ClickToFlash" button. For versions prior to 1.5b4, navigate to ~/Library/Internet Plug-ins/ in the Finder, where ~ is your home folder, and delete the item named "ClickToFlash.webplugin" (or "ClickToFlash.plugin"). + ##Version History * **1.5b3** [download](http://s3.amazonaws.com/clicktoflash/ClickToFlash-1.5b3.zip)