From f61aabde5c48d0b53e7aa41b9a345c1ee4da6273 Mon Sep 17 00:00:00 2001 From: ssp Date: Sun, 4 Oct 2009 15:15:11 +0200 Subject: [PATCH] More cleaning and FLV support on Vimeo. (Somehow Perian's FLV doesn't work when debugging but seems OK otherwise, so I think it's worth doing.) --- ClickToFlash.xcodeproj/project.pbxproj | 4 + Plugin/CTFKiller.h | 19 +++- Plugin/CTFKiller.m | 54 ++++++--- Plugin/CTFKillerVideo.h | 16 ++- Plugin/CTFKillerVideo.m | 39 ++++++- Plugin/CTFKillerVimeo.h | 29 +++-- Plugin/CTFKillerVimeo.m | 145 ++++++++++++++----------- Plugin/CTFKillerYouTube.m | 5 +- Plugin/Plugin.m | 25 +---- 9 files changed, 215 insertions(+), 121 deletions(-) diff --git a/ClickToFlash.xcodeproj/project.pbxproj b/ClickToFlash.xcodeproj/project.pbxproj index 0d29d81c..b0fb9bb9 100755 --- a/ClickToFlash.xcodeproj/project.pbxproj +++ b/ClickToFlash.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ 6953E43C0F3EDEB50014ECF7 /* MenubarMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6953E43A0F3EDEB50014ECF7 /* MenubarMenu.xib */; }; 69A26D0C0F302C10006648BC /* NSBezierPath-RoundedRectangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 69A26D0B0F302C10006648BC /* NSBezierPath-RoundedRectangle.m */; }; 6C2C5A6A1068CE8700A90A54 /* Credits.css in Resources */ = {isa = PBXBuildFile; fileRef = A40485B110629B0E00FDC4E2 /* Credits.css */; }; + 6C436DAF107830A200A0D525 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C436DAE107830A200A0D525 /* QTKit.framework */; }; 6C8EC6F410764F810053587F /* CTFKiller.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC6F310764F810053587F /* CTFKiller.m */; }; 6C8EC7051076544D0053587F /* CTFKillerYouTube.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC7041076544D0053587F /* CTFKillerYouTube.m */; }; 6C8EC775107671F20053587F /* CTFKillerVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C8EC774107671F20053587F /* CTFKillerVideo.m */; }; @@ -152,6 +153,7 @@ 6953E43B0F3EDEB50014ECF7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Plugin/English.lproj/MenubarMenu.xib; sourceTree = ""; }; 69A26D0A0F302C10006648BC /* NSBezierPath-RoundedRectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSBezierPath-RoundedRectangle.h"; path = "Plugin/NSBezierPath-RoundedRectangle.h"; sourceTree = ""; }; 69A26D0B0F302C10006648BC /* NSBezierPath-RoundedRectangle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSBezierPath-RoundedRectangle.m"; path = "Plugin/NSBezierPath-RoundedRectangle.m"; sourceTree = ""; }; + 6C436DAE107830A200A0D525 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = ""; }; 6C8EC6F210764F810053587F /* CTFKiller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFKiller.h; path = Plugin/CTFKiller.h; sourceTree = ""; }; 6C8EC6F310764F810053587F /* CTFKiller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTFKiller.m; path = Plugin/CTFKiller.m; sourceTree = ""; }; 6C8EC7031076544D0053587F /* CTFKillerYouTube.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTFKillerYouTube.h; path = Plugin/CTFKillerYouTube.h; sourceTree = ""; }; @@ -211,6 +213,7 @@ 55EB70580E04A8B80016593D /* Cocoa.framework in Frameworks */, 55EB70590E04A8B80016593D /* WebKit.framework in Frameworks */, 0038DE320FC0CE7B007B54E9 /* Carbon.framework in Frameworks */, + 6C436DAF107830A200A0D525 /* QTKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -291,6 +294,7 @@ 0038DE310FC0CE7B007B54E9 /* Carbon.framework */, 55EB70560E04A8B80016593D /* Cocoa.framework */, 55EB70570E04A8B80016593D /* WebKit.framework */, + 6C436DAE107830A200A0D525 /* QTKit.framework */, ); name = Frameworks; sourceTree = ""; diff --git a/Plugin/CTFKiller.h b/Plugin/CTFKiller.h index cec139e6..449d45c8 100644 --- a/Plugin/CTFKiller.h +++ b/Plugin/CTFKiller.h @@ -38,27 +38,40 @@ CTFClickToFlashPlugin * plugin; } +// Come and go + +// Class method returns an instantiated CTFKiller class for the URL/data/plugin passed to it. This is the call to use. + (CTFKiller*) killerForURL: (NSURL*) theURL src: (NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin; +// Initialiser method doing the basic setup. There should be no need to use this. The +killerForULR:src:attributes:forPlugin class method should handle everything. - (id) initWithURL: (NSURL*) theURL src:(NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin; -// to be implemented by subclasses +// To be implemented by subclasses + +// Return whether this class can handle the Flash for the given URL and other data. + (BOOL) canHandleFlashAtURL: (NSURL*) theURL src: (NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin; +// Set up the subclass. If further data is needed, fetching it is started here. - (void) setup; +// The label displayed in the plug-in. Subclasses can provide their own name here which is read whenever the plug-in view is redrawn. - (NSString*) badgeLabelText; +// Called when building the Contextual menu to add a single item at the second position. - (void) addPrincipalMenuItemToContextualMenu; +// Called when building the contextual menu to add further items afte the basic Load/Hide Flash items. - (void) addAdditionalMenuItemsForContextualMenu; +// Called when the user clicks the CtF view. Replace content here. - (BOOL) convertToContainer; -// accessors + +// Accessors - (NSURL *)pageURL; - (void)setPageURL:(NSURL *)newPageURL; - (NSString *)srcURLString; - (void)setSrcURLString:(NSString *)newSrcURLString; - (NSDictionary *)attributes; - (void)setAttributes:(NSDictionary *)newAttributes; -- (NSString*) flashVarWithName: (NSString*) argName; - (NSDictionary *)flashVars; - (void)setFlashVars:(NSDictionary *)newFlashVars; +// get a specific flash variable +- (NSString*) flashVarWithName: (NSString*) argName; - (CTFClickToFlashPlugin *)plugin; - (void)setPlugin:(CTFClickToFlashPlugin *)newPlugin; diff --git a/Plugin/CTFKiller.m b/Plugin/CTFKiller.m index 3fe0188f..a577c189 100644 --- a/Plugin/CTFKiller.m +++ b/Plugin/CTFKiller.m @@ -32,8 +32,14 @@ of this software and associated documentation files (the "Software"), to deal @implementation CTFKiller +#pragma mark - +#pragma mark Come and go + + +// Class method returns an instantiated CTFKiller class for the URL/data/plugin passed to it. This is the call to use. + (CTFKiller*) killerForURL: (NSURL*) theURL src: (NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin { CTFKiller * theKiller = nil; + NSArray * killerArray = [NSArray arrayWithObjects: NSClassFromString(@"CTFKillerYouTube"), NSClassFromString(@"CTFKillerVimeo"), NSClassFromString(@"CTFKillerSIFR"),nil]; NSEnumerator * myEnum = [killerArray objectEnumerator]; Class killerClass; @@ -48,11 +54,7 @@ + (CTFKiller*) killerForURL: (NSURL*) theURL src: (NSString*) theSrc attributes: } -+ (BOOL) canHandleFlashAtURL: (NSURL*) theURL src: (NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin { - return NO; -} - - +// Initialiser method doing the basic setup. There should be no need to use this. The +killerForULR:src:attributes:forPlugin class method should handle everything. - (id) initWithURL: (NSURL*) theURL src:(NSString*) theSrc attributes: (NSDictionary*) theAttributes forPlugin:(CTFClickToFlashPlugin*) thePlugin { self = [super init]; if (self != nil) { @@ -69,17 +71,6 @@ - (id) initWithURL: (NSURL*) theURL src:(NSString*) theSrc attributes: (NSDictio return self; } -- (void) setup { } - -- (NSString*) badgeLabelText { - return @"CTFKiller"; -} - -- (void) addPrincipalMenuItemToContextualMenu { } - -- (void) addAdditionalMenuItemsForContextualMenu { } - -- (BOOL) convertToContainer { return NO; } - (void) dealloc { @@ -95,7 +86,36 @@ - (void) dealloc { -#pragma mark ACCESSOR METHODS +#pragma mark - +#pragma mark Subclass overrides + +// Return whether this class can handle the Flash for the given URL and other data. ++ (BOOL) canHandleFlashAtURL: (NSURL*) theURL src: (NSString*) theSrc attributes: (NSDictionary*) attributes forPlugin:(CTFClickToFlashPlugin*) thePlugin { + return NO; +} + +// Set up the subclass. If further data is needed, fetching it is started here. +- (void) setup { } + +// The label displayed in the plug-in. Subclasses can provide their own name here which is read whenever the plug-in view is redrawn. +- (NSString*) badgeLabelText { return nil; } + +// Called when building the Contextual menu to add a single item at the second position. +- (void) addPrincipalMenuItemToContextualMenu { } + +// Called when building the contextual menu to add further items afte the basic Load/Hide Flash items. +- (void) addAdditionalMenuItemsForContextualMenu { } + +// Called when the user clicks the CtF view. Replace content here. +- (BOOL) convertToContainer { return NO; } + + + + + + +#pragma mark - +#pragma mark Accessors - (NSURL *)pageURL { diff --git a/Plugin/CTFKillerVideo.h b/Plugin/CTFKillerVideo.h index 61b76d55..0e64d65e 100644 --- a/Plugin/CTFKillerVideo.h +++ b/Plugin/CTFKillerVideo.h @@ -48,12 +48,17 @@ enum CTFKVLookupStatus { BOOL hasVideoHD; enum CTFKVLookupStatus lookupStatus; + BOOL requiresConversion; NSSize videoSize; NSURL * previewURL; } -// Subclasses should use setHasVideo and setHasVideoHD to indicate when they have determined movie paths. +/* + Subclasses use setHasVideo and setHasVideoHD to indicate when they have determined movie paths. + They set lookupStatus to indicate whether they are still busy doing lookups. Doing this will cause a redraw which can then alter the label text. +*/ + // to be implemented by subclasses if they want to @@ -80,10 +85,9 @@ enum CTFKVLookupStatus { // Edit or replace the markup that is added for the links beneath the video. The descriptionElement passed to the method already conatins Go to Webpage and Download Video File links. - (DOMElement *) enhanceVideoDescriptionElement: (DOMElement*) descriptionElement; - -// +// Indicate whether the current web page is the 'canonical' web page for the video. The default implementation compares the videoPageURLString with the current page's URL for that - (BOOL) isOnVideoPage; -- (NSString *) cleanURLString: (NSString*) URLString; + // Actions @@ -107,7 +111,9 @@ enum CTFKVLookupStatus { - (BOOL) useVideo; - (BOOL) useVideoHD; - (NSString *) videoURLStringForHD: (BOOL) useHD; +- (NSString *) cleanURLString: (NSString*) URLString; - (BOOL) isVideoElementAvailable; +- (void) finishedLookups; // Accessors - (BOOL) autoPlay; @@ -118,6 +124,8 @@ enum CTFKVLookupStatus { - (void) setHasVideoHD:(BOOL)newHasVideoHD; - (enum CTFKVLookupStatus) lookupStatus; - (void) setLookupStatus: (enum CTFKVLookupStatus) newLookupStatus; +- (BOOL)requiresConversion; +- (void)setRequiresConversion:(BOOL)newRequiresConversion; - (NSURL *) previewURL; - (void) setPreviewURL: (NSURL *) newPreviewURL; diff --git a/Plugin/CTFKillerVideo.m b/Plugin/CTFKillerVideo.m index b3ab27f9..c45a6e31 100644 --- a/Plugin/CTFKillerVideo.m +++ b/Plugin/CTFKillerVideo.m @@ -46,6 +46,9 @@ - (id) init { hasVideo = NO; hasVideoHD = NO; + lookupStatus = nothing; + requiresConversion = NO; + videoSize = NSZeroSize; [self setPreviewURL:nil]; } @@ -105,6 +108,8 @@ - (BOOL) isOnVideoPage { + + // Remove http:// and www. from beginning of URL. - (NSString *) cleanURLString: (NSString*) URLString { NSString * result = URLString; @@ -261,10 +266,14 @@ - (void) addAdditionalMenuItemsForContextualMenu; - (BOOL) convertToContainer { BOOL result = NO; - if ([self hasVideo]) { + if ([self lookupStatus] == finished && [self hasVideo]) { [self convertToMP4ContainerUsingHD:nil]; result = YES; } + else if ([self lookupStatus] == inProgress) { + [self setRequiresConversion: YES]; + result = YES; + } return result; } @@ -543,7 +552,7 @@ - (DOMElement*) linkContainerElementForURL: (NSString*) URLString { #pragma mark - -#pragma mark HELPER +#pragma mark Helpers // Determine whether we want to use the video. Returns YES if a video is available and the relevant preference is set. - (BOOL) useVideo { @@ -630,8 +639,18 @@ - (BOOL) isVideoElementAvailable +// Called when asynchronous lookups are finished. This will convert the element if it has been marked for conversion previously but the kind of conversion wasn't clear yet because of the pending lookups. +- (void) finishedLookups { + if ([self requiresConversion]) { + [self convertToContainer]; + } +} + + + -#pragma mark ACCESSORS +#pragma mark - +#pragma mark Accessors - (BOOL)autoPlay { BOOL result = autoPlay; @@ -670,10 +689,24 @@ - (enum CTFKVLookupStatus) lookupStatus { - (void) setLookupStatus: (enum CTFKVLookupStatus) newLookupStatus { lookupStatus = newLookupStatus; + if (lookupStatus == finished || lookupStatus == failed) { + [self finishedLookups]; + } [[self plugin] setNeedsDisplay: YES]; } +- (BOOL)requiresConversion +{ + return requiresConversion; +} + +- (void)setRequiresConversion:(BOOL)newRequiresConversion +{ + requiresConversion = newRequiresConversion; +} + + - (NSURL *)previewURL { return previewURL; } diff --git a/Plugin/CTFKillerVimeo.h b/Plugin/CTFKillerVimeo.h index fda733ae..7645e231 100644 --- a/Plugin/CTFKillerVimeo.h +++ b/Plugin/CTFKillerVimeo.h @@ -29,12 +29,21 @@ #import #import "CTFKillerVideo.h" +enum CTFVimeoConnectionType { + noConnection, + XML, + HEAD +}; + + @interface CTFKillerVimeo : CTFKillerVideo { NSString * clipID; NSString * clipSignature; NSString * clipExpires; + NSString * redirectedURLString; BOOL clipIsHD; + enum CTFVimeoConnectionType currentConnection; NSMutableData * downloadData; } @@ -43,15 +52,17 @@ - (void) getXML; - (void) finishXMLFetching: (NSURLConnection *) connection; - (void) finishHEADFetching: (NSURLConnection *) connection; -- (BOOL) isFetchingXML; -- (BOOL) isFetchingHEAD; - -- (NSString *)clipID; -- (void)setClipID:(NSString *)newClipID; -- (NSString *)clipSignature; -- (void)setClipSignature:(NSString *)newClipSignature; -- (NSString *)clipExpires; -- (void)setClipExpires:(NSString *)newClipExpires; + +- (NSString *) clipID; +- (void) setClipID: (NSString *) newClipID; +- (NSString *) clipSignature; +- (void) setClipSignature: (NSString *) newClipSignature; +- (NSString *) clipExpires; +- (void) setClipExpires: (NSString *) newClipExpires; +- (NSString *) redirectedURLString; +- (void) setRedirectedURLString: (NSString *) newRedirectedURLString; +- (enum CTFVimeoConnectionType) currentConnection; +- (void) setCurrentConnection: (enum CTFVimeoConnectionType) newConnectionType; @end diff --git a/Plugin/CTFKillerVimeo.m b/Plugin/CTFKillerVimeo.m index 3fe784a3..facbc5c9 100644 --- a/Plugin/CTFKillerVimeo.m +++ b/Plugin/CTFKillerVimeo.m @@ -30,6 +30,7 @@ of this software and associated documentation files (the "Software"), to deal #import "Plugin.h" #import "CTFUtilities.h" #import "CTFUserDefaultsController.h" +#import @implementation CTFKillerVimeo @@ -54,9 +55,12 @@ - (void) setup { [self setClipID: nil]; [self setClipSignature: nil]; [self setClipExpires: nil]; + [self setRedirectedURLString: nil]; downloadData = nil; + currentConnection = noConnection; lookupStatus = nothing; + NSString * myID = [ self flashVarWithName:@"clip_id" ]; if (myID == nil) { @@ -80,6 +84,7 @@ - (void) dealloc { [self setClipID: nil]; [self setClipSignature: nil]; [self setClipExpires: nil]; + [self setRedirectedURLString: nil]; [super dealloc]; } @@ -99,19 +104,14 @@ - (NSString*) siteName { // URL to the video file used for loading it in the player. - (NSString *) videoURLString { - NSString * URLString = nil; - - if ( clipID != nil && clipSignature != nil && clipExpires != nil) { - URLString = [NSString stringWithFormat:@"http://vimeo.com/moogaloop/play/clip:%@/%@/%@/", clipID, clipSignature, clipExpires]; - } - + NSString * URLString = [self redirectedURLString]; return URLString; } - (NSString *) videoHDURLString { NSString * URLString = nil; - URLString = [[self videoURLString] stringByAppendingString:@"/?q=hd"]; + URLString = [[self videoURLString] stringByAppendingString:@"?q=hd"]; return URLString; } @@ -136,16 +136,18 @@ - (NSString *) videoPageURLString { /* 1. download the XML file which provides the keys required to construct the URL to access the video file - 2. get headers for the video file to check whether it actually is MP4 + 2. get headers for the video file to figure out its file format. MP4 URL seem to be usable right away, but FLV URL (which require Perian anyway) seem to include a redirect which the WebKit video element doesn't seem to resolve. [e.g http://vimeo.com/1039366 doesn't seem to have a MP4 version] + 3. For FLV files resolve the redirect. */ - (void) getXML { NSString * XMLURLString = [NSString stringWithFormat:@"http://vimeo.com/moogaloop/load/clip:%@", [self clipID]]; NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString:XMLURLString]]; if (request != nil) { - downloadData = [[NSMutableData alloc] initWithLength:20000]; + downloadData = [[NSMutableData alloc] initWithLength: 20000]; [NSURLConnection connectionWithRequest: request delegate:self]; + [self setCurrentConnection: XML]; [self setLookupStatus: inProgress]; } else { @@ -155,16 +157,19 @@ - (void) getXML { - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { - [downloadData appendData:data]; + if ( [self currentConnection] == XML ) { + [downloadData appendData:data]; + } } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - if ([self isFetchingXML]) { + if ( [self currentConnection] == XML ) { // only run when fetching the XML file, not for the video file header - NSError * error; + NSError * error = nil; NSXMLDocument * XML = [[[NSXMLDocument alloc] initWithData:downloadData options:NSXMLDocumentTidyXML error:&error] autorelease]; [self finishXMLFetching: connection]; + [self setCurrentConnection: noConnection]; NSXMLNode * node; if (XML != nil) { @@ -204,10 +209,13 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { } - // Now we collected the data but vimeo seem to have two video formats in the background flv/mp4. The only way I see so far to tell those apart is from the MIME Type of the video file's URL. Any better way to do this would be great. - NSMutableURLRequest * request = [[[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:[self videoURLString]]] autorelease]; + // Now we collected the data but vimeo seem to have two video formats in the background flv/mp4. The only way I see so far to tell those apart is from the MIME Type of the video file's URL. Any better way to do this would be great. + NSString * HEADURLString = [NSString stringWithFormat:@"http://vimeo.com/moogaloop/play/clip:%@/%@/%@/", [self clipID], [self clipSignature], [self clipExpires]]; + + NSMutableURLRequest * request = [[[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: HEADURLString]] autorelease]; if (request != nil) { [request setHTTPMethod:@"HEAD"]; + [self setCurrentConnection: HEAD]; [NSURLConnection connectionWithRequest: request delegate: self]; } else { @@ -219,29 +227,43 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - if ( [self isFetchingXML]) { - [self finishXMLFetching: connection]; - } - else { - [self finishHEADFetching: connection]; + switch ([self currentConnection]) { + case XML: + [self finishXMLFetching: connection]; + break; + case HEAD: + [self finishHEADFetching: connection]; + break; + default: + break; } + + [self setCurrentConnection: noConnection ]; [self setLookupStatus: failed]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { - // Only run this for the head fetching connection - if ( [self isFetchingHEAD] ) { - NSInteger statusCode = [response statusCode]; - NSString * contentType = [response MIMEType]; - - if ( statusCode == 200 && [contentType isEqualToString: @"video/mp4"] ) { - [self setHasVideo: YES]; - [self setLookupStatus: finished]; + NSInteger statusCode = [response statusCode]; + NSString * contentType = [response MIMEType]; + + if ( [self currentConnection] == HEAD ) { + if ( statusCode == 200 ) { + if ([contentType isEqualToString: @"video/mp4"] ) { + [self setHasVideo: YES]; + [self setLookupStatus: finished]; + } + else if ( [contentType isEqualToString: @"video/x-flv"] ) { + if ( [[QTMovie movieFileTypes: QTIncludeCommonTypes] containsObject: @"flv"] ) { + // QuickTime can play flv (Perian?) + [self setHasVideo: YES]; + } + } } - - [self finishHEADFetching: connection]; + [self finishHEADFetching: connection]; + [self setCurrentConnection: noConnection]; + [self setLookupStatus: finished]; } } @@ -253,7 +275,6 @@ - (void) finishXMLFetching: (NSURLConnection *) connection { downloadData = nil; } - - (void) finishHEADFetching: (NSURLConnection *) connection { [connection cancel]; } @@ -265,74 +286,74 @@ - (NSURLRequest *)connection:(NSURLConnection *)connection redirectResponse:(NSURLResponse *)redirectResponse { NSURLRequest * result = request; - +// NSLog(@"type %i, redirect to: %@", [self currentConnection], [[request URL] absoluteString]); + // For the head fetching we need to fix the redirects to make sure the method they use is HEAD. - if ( [self isFetchingHEAD] ) { + if ( [self currentConnection] == HEAD ) { if (![[request HTTPMethod] isEqualTo:@"HEAD"]) { NSMutableURLRequest * newRequest = [[request mutableCopy] autorelease]; [newRequest setHTTPMethod:@"HEAD"]; result = newRequest; } - } - - return result; -} - - -// At most one connection runs at a time, if the downloadData variable is non-nil, it's the XML connection. Only for use inside the fetching methods. -- (BOOL) isFetchingXML { - BOOL result = (downloadData != nil); - return result; -} - - -- (BOOL) isFetchingHEAD { - BOOL result = (downloadData == nil); + [self setRedirectedURLString: [[request URL] absoluteString]]; + } + return result; } +#pragma mark - +#pragma mark Accessors - -#pragma mark ACCESSORS - -- (NSString *)clipID -{ +- (NSString *) clipID { return clipID; } -- (void)setClipID:(NSString *)newClipID -{ +- (void) setClipID: (NSString *) newClipID { [newClipID retain]; [clipID release]; clipID = newClipID; } -- (NSString *)clipSignature -{ +- (NSString *) clipSignature { return clipSignature; } -- (void)setClipSignature:(NSString *)newClipSignature -{ +- (void) setClipSignature: (NSString *) newClipSignature { [newClipSignature retain]; [clipSignature release]; clipSignature = newClipSignature; } -- (NSString *)clipExpires -{ +- (NSString *) clipExpires { return clipExpires; } -- (void)setClipExpires:(NSString *)newClipExpires -{ +- (void) setClipExpires: (NSString *) newClipExpires { [newClipExpires retain]; [clipExpires release]; clipExpires = newClipExpires; } +- (NSString *) redirectedURLString { + return redirectedURLString; +} + +- (void) setRedirectedURLString: (NSString *) newRedirectedURLString { + [newRedirectedURLString retain]; + [redirectedURLString release]; + redirectedURLString = newRedirectedURLString; +} + + +- (enum CTFVimeoConnectionType) currentConnection { + return currentConnection; +} + +- (void) setCurrentConnection: (enum CTFVimeoConnectionType) newConnectionType { + currentConnection = newConnectionType; +} @end diff --git a/Plugin/CTFKillerYouTube.m b/Plugin/CTFKillerYouTube.m index 31bb9eab..428cddb2 100644 --- a/Plugin/CTFKillerYouTube.m +++ b/Plugin/CTFKillerYouTube.m @@ -76,6 +76,7 @@ - (void) setup { // methods already spawn separate threads for the data retrieval, // so no need to spawn a separate thread + [self setLookupStatus: inProgress]; [self _checkForH264VideoVariants]; } else { @@ -104,12 +105,13 @@ - (void) setup { // additional data from the internets, so we want to spin this off // to another thread to prevent blocking of the Safari user interface + [self setLookupStatus: inProgress]; // this method is a stub for calling the real method on a different thread [self _getEmbeddedPlayerFlashVarsAndCheckForVariantsWithVideoId:videoID]; } } - if ([CTFKillerYouTube isYouTubeSiteURL: pageURL]){ + if ([CTFKillerYouTube isYouTubeSiteURL: pageURL]) { [self setAutoPlay: YES]; } else { [self setAutoPlay: [[self flashVarWithName: @"autoplay"] isEqualToString:@"1"]]; @@ -201,7 +203,6 @@ - (void)_checkForH264VideoVariants expectedResponses = 2; receivedAllResponses = NO; - [self setLookupStatus: inProgress]; } diff --git a/Plugin/Plugin.m b/Plugin/Plugin.m index 98579a0d..a1ab2041 100755 --- a/Plugin/Plugin.m +++ b/Plugin/Plugin.m @@ -168,7 +168,7 @@ - (id) initWithArguments:(NSDictionary *)arguments _flashVars = [ [ CTFClickToFlashPlugin flashVarDictionary: flashvars ] retain ]; - // Check whether one of our killers can handle this + // Set up the CTFKiller subclass, if appropriate. [self setKiller: [CTFKiller killerForURL:[NSURL URLWithString:[self baseURL]] src:[self src] attributes:[self attributes] forPlugin:self]]; _fromFlickr = [[self host] rangeOfString:@"flickr.com"].location != NSNotFound; @@ -234,27 +234,8 @@ - (id) initWithArguments:(NSDictionary *)arguments if(loadFromWhiteList && ![self _isOptionPressed]) { _isLoadingFromWhitelist = YES; + [self convertTypesForContainer]; -// #warning REQUIRES ATTENTION - if (_fromYouTube) { - // we do this because checking for H.264 variants is handled - // on another thread, so the results of that check may not have - // been returned yet; if the user has this site on a whitelist - // and the results haven't been returned, then the *Flash* will - // load (ewwwwwww!) instead of the H.264, even if the user's - // preferences are for the H.264 - - // the _checkForH264VideoVariants method will manually fire - // this timer if it finishes before the 3 seconds are up - _delayingTimer = [NSTimer scheduledTimerWithTimeInterval:3 - target:self - selector:@selector(convertTypesForContainer) - userInfo:nil - repeats:NO]; - } else { - [self convertTypesForContainer]; - } - return self; } @@ -338,6 +319,8 @@ - (id) initWithArguments:(NSDictionary *)arguments return self; } + + - (void)webPlugInDestroy { [self _removeTrackingAreaForCTF];